|
|
@@ -1,5 +1,5 @@
|
|
|
<?xml version="1.0" encoding="UTF-8"?>
|
|
|
-<!-- EN-Revision: 15103 -->
|
|
|
+<!-- EN-Revision: 17598 -->
|
|
|
<!-- Reviewed: no -->
|
|
|
<sect1 id="zend.db.table.relationships">
|
|
|
|
|
|
@@ -16,7 +16,8 @@
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The <classname>Zend_Db_Table_Row</classname> class has methods for querying related rows in other tables.
|
|
|
+ The <classname>Zend_Db_Table_Row</classname> class has methods for querying related rows
|
|
|
+ in other tables.
|
|
|
</para>
|
|
|
|
|
|
</sect2>
|
|
|
@@ -27,7 +28,8 @@
|
|
|
|
|
|
<para>
|
|
|
Define classes for each of your tables, extending the abstract class
|
|
|
- <classname>Zend_Db_Table_Abstract</classname>, as described in <xref linkend="zend.db.table.defining" />. Also
|
|
|
+ <classname>Zend_Db_Table_Abstract</classname>, as described in
|
|
|
+ <xref linkend="zend.db.table.defining" />. Also
|
|
|
see <xref linkend="zend.db.adapter.example-database" /> for a description of the
|
|
|
example database for which the following example code is designed.
|
|
|
</para>
|
|
|
@@ -36,7 +38,7 @@
|
|
|
Below are the <acronym>PHP</acronym> class definitions for these tables:
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
class Accounts extends Zend_Db_Table_Abstract
|
|
|
{
|
|
|
protected $_name = 'accounts';
|
|
|
@@ -95,44 +97,45 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
]]></programlisting>
|
|
|
|
|
|
<para>
|
|
|
- If you use <classname>Zend_Db_Table</classname> to emulate cascading UPDATE and DELETE operations, declare the
|
|
|
- <methodname>$_dependentTables</methodname> array in the class for the parent table. List the class
|
|
|
- name for each dependent table. Use the class name, not the physical name of the SQL
|
|
|
- table.
|
|
|
+ If you use <classname>Zend_Db_Table</classname> to emulate cascading UPDATE and DELETE
|
|
|
+ operations, declare the <varname>$_dependentTables</varname> array in the class for the
|
|
|
+ parent table. List the class name for each dependent table. Use the class name, not the
|
|
|
+ physical name of the <acronym>SQL</acronym> table.
|
|
|
</para>
|
|
|
|
|
|
<note>
|
|
|
|
|
|
<para>
|
|
|
- Skip declaration of <methodname>$_dependentTables</methodname> if you use referential integrity
|
|
|
- constraints in the <acronym>RDBMS</acronym> server to implement cascading operations. See
|
|
|
- <xref linkend="zend.db.table.relationships.cascading" /> for more information.
|
|
|
+ Skip declaration of <varname>$_dependentTables</varname> if you use referential
|
|
|
+ integrity constraints in the <acronym>RDBMS</acronym> server to implement cascading
|
|
|
+ operations. See <xref linkend="zend.db.table.relationships.cascading" /> for more
|
|
|
+ information.
|
|
|
</para>
|
|
|
|
|
|
</note>
|
|
|
|
|
|
<para>
|
|
|
- Declare the <methodname>$_referenceMap</methodname> array in the class for each dependent table.
|
|
|
- This is an associative array of reference "rules". A reference rule identifies which
|
|
|
- table is the parent table in the relationship, and also lists which columns in the
|
|
|
+ Declare the <varname>$_referenceMap</varname> array in the class for each dependent
|
|
|
+ table. This is an associative array of reference "rules". A reference rule identifies
|
|
|
+ which table is the parent table in the relationship, and also lists which columns in the
|
|
|
dependent table reference which columns in the parent table.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The rule key is a string used as an index to the <methodname>$_referenceMap</methodname> array.
|
|
|
- This rule key is used to identify each reference relationship. Choose a descriptive
|
|
|
- name for this rule key. It's best to use a string that can be part of a <acronym>PHP</acronym> method
|
|
|
- name, as you will see later.
|
|
|
+ The rule key is a string used as an index to the <varname>$_referenceMap</varname>
|
|
|
+ array. This rule key is used to identify each reference relationship. Choose a
|
|
|
+ descriptive name for this rule key. It's best to use a string that can be part of a
|
|
|
+ <acronym>PHP</acronym> method name, as you will see later.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- In the example <acronym>PHP</acronym> code above, the rule keys in the Bugs table class are:
|
|
|
- <methodname>'Reporter'</methodname>, <methodname>'Engineer'</methodname>, <methodname>'Verifier'</methodname>, and
|
|
|
- <methodname>'Product'</methodname>.
|
|
|
+ In the example <acronym>PHP</acronym> code above, the rule keys in the Bugs table class
|
|
|
+ are: <code>'Reporter'</code>, <code>'Engineer'</code>, <code>'Verifier'</code>, and
|
|
|
+ <code>'Product'</code>.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The value of each rule entry in the <methodname>$_referenceMap</methodname> array is also an
|
|
|
+ The value of each rule entry in the <varname>$_referenceMap</varname> array is also an
|
|
|
associative array. The elements of this rule entry are described below:
|
|
|
</para>
|
|
|
|
|
|
@@ -151,17 +154,17 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <emphasis>refTableClass</emphasis> => The class name of the
|
|
|
- parent table. Use the class name, not the physical name of the <acronym>SQL</acronym> table.
|
|
|
+ <emphasis>refTableClass</emphasis> => The class name of the parent table. Use
|
|
|
+ the class name, not the physical name of the <acronym>SQL</acronym> table.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
It's common for a dependent table to have only one reference to its parent
|
|
|
table, but some tables have multiple references to the same parent table. In
|
|
|
- the example database, there is one reference from the <methodname>bugs</methodname> table
|
|
|
- to the <methodname>products</methodname> table, but three references from the
|
|
|
- <methodname>bugs</methodname> table to the <methodname>accounts</methodname> table. Put each reference
|
|
|
- in a separate entry in the <methodname>$_referenceMap</methodname> array.
|
|
|
+ the example database, there is one reference from the <code>bugs</code> table
|
|
|
+ to the <code>products</code> table, but three references from the
|
|
|
+ <code>bugs</code> table to the <code>accounts</code> table. Put each reference
|
|
|
+ in a separate entry in the <varname>$_referenceMap</varname> array.
|
|
|
</para>
|
|
|
</listitem>
|
|
|
|
|
|
@@ -174,13 +177,13 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
<para>
|
|
|
It's common for this to be a single column, but some tables have multi-column
|
|
|
keys. If the reference uses a multi-column key, the order of columns in the
|
|
|
- <methodname>'columns'</methodname> entry must match the order of columns in the
|
|
|
- <methodname>'refColumns'</methodname> entry.
|
|
|
+ <code>'columns'</code> entry must match the order of columns in the
|
|
|
+ <code>'refColumns'</code> entry.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
It is optional to specify this element. If you don't specify the
|
|
|
- <methodname>refColumns</methodname>, the column(s) reported as the primary key columns of
|
|
|
+ <code>refColumns</code>, the column(s) reported as the primary key columns of
|
|
|
the parent table are used by default.
|
|
|
</para>
|
|
|
</listitem>
|
|
|
@@ -213,20 +216,20 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
from dependent tables that reference the current row. Use the method:
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$row->findDependentRowset($table, [$rule]);
|
|
|
]]></programlisting>
|
|
|
|
|
|
<para>
|
|
|
- This method returns a <classname>Zend_Db_Table_Rowset_Abstract</classname> object, containing a set of rows
|
|
|
- from the dependent table <methodname>$table</methodname> that refer to the row identified by the
|
|
|
- <methodname>$row</methodname> object.
|
|
|
+ This method returns a <classname>Zend_Db_Table_Rowset_Abstract</classname> object,
|
|
|
+ containing a set of rows from the dependent table <varname>$table</varname> that refer
|
|
|
+ to the row identified by the <varname>$row</varname> object.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The first argument <methodname>$table</methodname> can be a string that specifies the dependent
|
|
|
- table by its class name. You can also specify the dependent table by using an object of
|
|
|
- that table class.
|
|
|
+ The first argument <varname>$table</varname> can be a string that specifies the
|
|
|
+ dependent table by its class name. You can also specify the dependent table by using an
|
|
|
+ object of that table class.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.dependent.example">
|
|
|
@@ -234,11 +237,11 @@ $row->findDependentRowset($table, [$rule]);
|
|
|
<title>Fetching a Dependent Rowset</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from the table <methodname>Accounts</methodname>, and
|
|
|
- finding the <methodname>Bugs</methodname> reported by that account.
|
|
|
+ This example shows getting a Row object from the table <code>Accounts</code>, and
|
|
|
+ finding the <code>Bugs</code> reported by that account.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
|
$accountsRowset = $accountsTable->find(1234);
|
|
|
$user1234 = $accountsRowset->current();
|
|
|
@@ -249,16 +252,16 @@ $bugsReportedByUser = $user1234->findDependentRowset('Bugs');
|
|
|
</example>
|
|
|
|
|
|
<para>
|
|
|
- The second argument <methodname>$rule</methodname> is optional. It is a string that names the rule
|
|
|
- key in the <methodname>$_referenceMap</methodname> array of the dependent table class. If you don't
|
|
|
- specify a rule, the first rule in the array that references the parent table is used.
|
|
|
- If you need to use a rule other than the first, you need to specify the key.
|
|
|
+ The second argument <varname>$rule</varname> is optional. It is a string that names the
|
|
|
+ rule key in the <varname>$_referenceMap</varname> array of the dependent table class. If
|
|
|
+ you don't specify a rule, the first rule in the array that references the parent table
|
|
|
+ is used. If you need to use a rule other than the first, you need to specify the key.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
In the example code above, the rule key is not specified, so the rule used by default
|
|
|
is the first one that matches the parent table. This is the rule
|
|
|
- <methodname>'Reporter'</methodname>.
|
|
|
+ <code>'Reporter'</code>.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.dependent.example-by">
|
|
|
@@ -266,13 +269,13 @@ $bugsReportedByUser = $user1234->findDependentRowset('Bugs');
|
|
|
<title>Fetching a Dependent Rowset By a Specific Rule</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from the table <methodname>Accounts</methodname>, and
|
|
|
- finding the <methodname>Bugs</methodname> assigned to be fixed by the user of that account. The
|
|
|
+ This example shows getting a Row object from the table <code>Accounts</code>, and
|
|
|
+ finding the <code>Bugs</code> assigned to be fixed by the user of that account. The
|
|
|
rule key string that corresponds to this reference relationship in this example is
|
|
|
- <methodname>'Engineer'</methodname>.
|
|
|
+ <code>'Engineer'</code>.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
|
$accountsRowset = $accountsTable->find(1234);
|
|
|
$user1234 = $accountsRowset->current();
|
|
|
@@ -294,12 +297,12 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs', 'Engineer');
|
|
|
<title>Fetching a Dependent Rowset using a Zend_Db_Table_Select</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from the table <methodname>Accounts</methodname>,
|
|
|
- and finding the <methodname>Bugs</methodname> assigned to be fixed by the user of that
|
|
|
+ This example shows getting a Row object from the table <code>Accounts</code>,
|
|
|
+ and finding the <code>Bugs</code> assigned to be fixed by the user of that
|
|
|
account, limited only to 3 rows and ordered by name.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
|
$accountsRowset = $accountsTable->find(1234);
|
|
|
$user1234 = $accountsRowset->current();
|
|
|
@@ -314,29 +317,30 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
</example>
|
|
|
|
|
|
Alternatively, you can query rows from a dependent table using a special mechanism
|
|
|
- called a "magic method". <classname>Zend_Db_Table_Row_Abstract</classname> invokes the method:
|
|
|
- <methodname>findDependentRowset('<TableClass>', '<Rule>')</methodname> if you invoke a method on
|
|
|
- the Row object matching either of the following patterns:
|
|
|
+ called a "magic method". <classname>Zend_Db_Table_Row_Abstract</classname> invokes the
|
|
|
+ method: <methodname>findDependentRowset('<TableClass>',
|
|
|
+ '<Rule>')</methodname> if you invoke a method on the Row object matching
|
|
|
+ either of the following patterns:
|
|
|
</para>
|
|
|
|
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->find<TableClass>()</methodname>
|
|
|
+ <code>$row->find<TableClass>()</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->find<TableClass>By<Rule>()</methodname>
|
|
|
+ <code>$row->find<TableClass>By<Rule>()</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
|
|
|
|
<para>
|
|
|
- In the patterns above, <methodname><TableClass></methodname> and <methodname><Rule></methodname> are strings
|
|
|
- that correspond to the class name of the dependent table, and the dependent table's
|
|
|
- rule key that references the parent table.
|
|
|
+ In the patterns above, <code><TableClass></code> and <code><Rule></code> are
|
|
|
+ strings that correspond to the class name of the dependent table, and the dependent
|
|
|
+ table's rule key that references the parent table.
|
|
|
</para>
|
|
|
|
|
|
<note>
|
|
|
@@ -344,9 +348,9 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
<para>
|
|
|
Some application frameworks, such as Ruby on Rails, use a mechanism called
|
|
|
"inflection" to allow the spelling of identifiers to change depending on usage. For
|
|
|
- simplicity, <classname>Zend_Db_Table_Row</classname> does not provide any inflection mechanism. The table
|
|
|
- identity and the rule key named in the method call must match the spelling of the
|
|
|
- class and rule key exactly.
|
|
|
+ simplicity, <classname>Zend_Db_Table_Row</classname> does not provide any inflection
|
|
|
+ mechanism. The table identity and the rule key named in the method call must match
|
|
|
+ the spelling of the class and rule key exactly.
|
|
|
</para>
|
|
|
|
|
|
</note>
|
|
|
@@ -361,7 +365,7 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
specifying the table and rule as strings.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
|
$accountsRowset = $accountsTable->find(1234);
|
|
|
$user1234 = $accountsRowset->current();
|
|
|
@@ -386,7 +390,7 @@ $bugsAssignedTo = $user1234->findBugsByEngineer();
|
|
|
the row in the parent to which the dependent row refers. Use the method:
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$row->findParentRow($table, [$rule]);
|
|
|
]]></programlisting>
|
|
|
|
|
|
@@ -396,9 +400,9 @@ $row->findParentRow($table, [$rule]);
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The first argument <methodname>$table</methodname> can be a string that specifies the parent table
|
|
|
- by its class name. You can also specify the parent table by using an object of that
|
|
|
- table class.
|
|
|
+ The first argument <varname>$table</varname> can be a string that specifies the parent
|
|
|
+ table by its class name. You can also specify the parent table by using an object of
|
|
|
+ that table class.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.parent.example">
|
|
|
@@ -406,12 +410,12 @@ $row->findParentRow($table, [$rule]);
|
|
|
<title>Fetching the Parent Row</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from the table <methodname>Bugs</methodname> (for
|
|
|
+ This example shows getting a Row object from the table <code>Bugs</code> (for
|
|
|
example one of those bugs with status 'NEW'), and finding the row in the
|
|
|
- <methodname>Accounts</methodname> table for the user who reported the bug.
|
|
|
+ <code>Accounts</code> table for the user who reported the bug.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->fetchAll(array('bug_status = ?' => 'NEW'));
|
|
|
$bug1 = $bugsRowset->current();
|
|
|
@@ -422,15 +426,15 @@ $reporter = $bug1->findParentRow('Accounts');
|
|
|
</example>
|
|
|
|
|
|
<para>
|
|
|
- The second argument <methodname>$rule</methodname> is optional. It is a string that names the rule
|
|
|
- key in the <methodname>$_referenceMap</methodname> array of the dependent table class. If you don't
|
|
|
- specify a rule, the first rule in the array that references the parent table is used.
|
|
|
- If you need to use a rule other than the first, you need to specify the key.
|
|
|
+ The second argument <varname>$rule</varname> is optional. It is a string that names the
|
|
|
+ rule key in the <varname>$_referenceMap</varname> array of the dependent table class. If
|
|
|
+ you don't specify a rule, the first rule in the array that references the parent table
|
|
|
+ is used. If you need to use a rule other than the first, you need to specify the key.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
In the example above, the rule key is not specified, so the rule used by default is the
|
|
|
- first one that matches the parent table. This is the rule <methodname>'Reporter'</methodname>.
|
|
|
+ first one that matches the parent table. This is the rule <code>'Reporter'</code>.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.parent.example-by">
|
|
|
@@ -438,13 +442,13 @@ $reporter = $bug1->findParentRow('Accounts');
|
|
|
<title>Fetching a Parent Row By a Specific Rule</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from the table <methodname>Bugs</methodname>, and
|
|
|
+ This example shows getting a Row object from the table <code>Bugs</code>, and
|
|
|
finding the account for the engineer assigned to fix that bug. The rule key string
|
|
|
that corresponds to this reference relationship in this example is
|
|
|
- <methodname>'Engineer'</methodname>.
|
|
|
+ <code>'Engineer'</code>.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->fetchAll(array('bug_status = ?', 'NEW'));
|
|
|
$bug1 = $bugsRowset->current();
|
|
|
@@ -457,27 +461,27 @@ $engineer = $bug1->findParentRow('Accounts', 'Engineer');
|
|
|
<para>
|
|
|
Alternatively, you can query rows from a parent table using a "magic method".
|
|
|
<classname>Zend_Db_Table_Row_Abstract</classname> invokes the method:
|
|
|
- <methodname>findParentRow('<TableClass>', '<Rule>')</methodname> if you invoke a method
|
|
|
- on the Row object matching either of the following patterns:
|
|
|
+ <methodname>findParentRow('<TableClass>', '<Rule>')</methodname> if you
|
|
|
+ invoke a method on the Row object matching either of the following patterns:
|
|
|
</para>
|
|
|
|
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->findParent<TableClass>([Zend_Db_Table_Select $select])</methodname>
|
|
|
+ <code>$row->findParent<TableClass>([Zend_Db_Table_Select $select])</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->findParent<TableClass>By<Rule>([Zend_Db_Table_Select
|
|
|
- $select])</methodname>
|
|
|
+ <code>$row->findParent<TableClass>By<Rule>([Zend_Db_Table_Select
|
|
|
+ $select])</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
|
|
|
|
<para>
|
|
|
- In the patterns above, <methodname><TableClass></methodname> and <methodname><Rule></methodname>
|
|
|
+ In the patterns above, <code><TableClass></code> and <code><Rule></code>
|
|
|
are strings that correspond to the class name of the parent table, and the dependent
|
|
|
table's rule key that references the parent table.
|
|
|
</para>
|
|
|
@@ -501,7 +505,7 @@ $engineer = $bug1->findParentRow('Accounts', 'Engineer');
|
|
|
specifying the table and rule as strings.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->fetchAll(array('bug_status = ?', 'NEW'));
|
|
|
$bug1 = $bugsRowset->current();
|
|
|
@@ -528,7 +532,7 @@ $engineer = $bug1->findParentAccountsByEngineer();
|
|
|
intersection table. Use the method:
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$row->findManyToManyRowset($table,
|
|
|
$intersectionTable,
|
|
|
[$rule1,
|
|
|
@@ -539,22 +543,22 @@ $row->findManyToManyRowset($table,
|
|
|
]]></programlisting>
|
|
|
|
|
|
<para>
|
|
|
- This method returns a <classname>Zend_Db_Table_Rowset_Abstract</classname> containing rows from the table
|
|
|
- <methodname>$table</methodname>, satisfying the many-to-many relationship. The current Row object
|
|
|
- <methodname>$row</methodname> from the origin table is used to find rows in the intersection table,
|
|
|
- and that is joined to the destination table.
|
|
|
+ This method returns a <classname>Zend_Db_Table_Rowset_Abstract</classname> containing
|
|
|
+ rows from the table <varname>$table</varname>, satisfying the many-to-many relationship.
|
|
|
+ The current Row object <varname>$row</varname> from the origin table is used to find
|
|
|
+ rows in the intersection table, and that is joined to the destination table.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The first argument <methodname>$table</methodname> can be a string that specifies the destination
|
|
|
- table in the many-to-many relationship by its class name. You can also specify the
|
|
|
- destination table by using an object of that table class.
|
|
|
+ The first argument <varname>$table</varname> can be a string that specifies the
|
|
|
+ destination table in the many-to-many relationship by its class name. You can also
|
|
|
+ specify the destination table by using an object of that table class.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The second argument <methodname>$intersectionTable</methodname> can be a string that specifies the
|
|
|
- intersection table between the two tables in the the many-to-many relationship by its
|
|
|
- class name. You can also specify the intersection table by using an object of that
|
|
|
+ The second argument <varname>$intersectionTable</varname> can be a string that specifies
|
|
|
+ the intersection table between the two tables in the many-to-many relationship by
|
|
|
+ its class name. You can also specify the intersection table by using an object of that
|
|
|
table class.
|
|
|
</para>
|
|
|
|
|
|
@@ -563,12 +567,12 @@ $row->findManyToManyRowset($table,
|
|
|
<title>Fetching a Rowset with the Many-to-many Method</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows getting a Row object from from the origin table
|
|
|
- <methodname>Bugs</methodname>, and finding rows from the destination table
|
|
|
- <methodname>Products</methodname>, representing products related to that bug.
|
|
|
+ This example shows getting a Row object from the origin table
|
|
|
+ <code>Bugs</code>, and finding rows from the destination table
|
|
|
+ <code>Products</code>, representing products related to that bug.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->find(1234);
|
|
|
$bug1234 = $bugsRowset->current();
|
|
|
@@ -580,34 +584,34 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
</example>
|
|
|
|
|
|
<para>
|
|
|
- The third and fourth arguments <methodname>$rule1</methodname> and <methodname>$rule2</methodname> are
|
|
|
- optional. These are strings that name the rule keys in the <methodname>$_referenceMap</methodname>
|
|
|
- array of the intersection table.
|
|
|
+ The third and fourth arguments <varname>$rule1</varname> and <varname>$rule2</varname>
|
|
|
+ are optional. These are strings that name the rule keys in the
|
|
|
+ <varname>$_referenceMap</varname> array of the intersection table.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The <methodname>$rule1</methodname> key names the rule for the relationship from the intersection
|
|
|
- table to the origin table. In this example, this is the relationship from
|
|
|
- <methodname>BugsProducts</methodname> to <methodname>Bugs</methodname>.
|
|
|
+ The <varname>$rule1</varname> key names the rule for the relationship from the
|
|
|
+ intersection table to the origin table. In this example, this is the relationship from
|
|
|
+ <code>BugsProducts</code> to <code>Bugs</code>.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- The <methodname>$rule2</methodname> key names the rule for the relationship from the intersection
|
|
|
- table to the destination table. In this example, this is the relationship from
|
|
|
- <methodname>Bugs</methodname> to <methodname>Products</methodname>.
|
|
|
+ The <varname>$rule2</varname> key names the rule for the relationship from the
|
|
|
+ intersection table to the destination table. In this example, this is the relationship
|
|
|
+ from <code>Bugs</code> to <code>Products</code>.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
Similarly to the methods for finding parent and dependent rows, if you don't specify a
|
|
|
- rule, the method uses the first rule in the <methodname>$_referenceMap</methodname> array that
|
|
|
+ rule, the method uses the first rule in the <varname>$_referenceMap</varname> array that
|
|
|
matches the tables in the relationship. If you need to use a rule other than the first,
|
|
|
you need to specify the key.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
In the example code above, the rule key is not specified, so the rules used by default
|
|
|
- are the first ones that match. In this case, <methodname>$rule1</methodname> is
|
|
|
- <methodname>'Reporter'</methodname> and <methodname>$rule2</methodname> is <methodname>'Product'</methodname>.
|
|
|
+ are the first ones that match. In this case, <varname>$rule1</varname> is
|
|
|
+ <code>'Reporter'</code> and <varname>$rule2</varname> is <code>'Product'</code>.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example-by">
|
|
|
@@ -615,12 +619,12 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
<title>Fetching a Rowset with the Many-to-many Method By a Specific Rule</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows geting a Row object from from the origin table
|
|
|
- <methodname>Bugs</methodname>, and finding rows from the destination table
|
|
|
- <methodname>Products</methodname>, representing products related to that bug.
|
|
|
+ This example shows geting a Row object from the origin table
|
|
|
+ <code>Bugs</code>, and finding rows from the destination table
|
|
|
+ <code>Products</code>, representing products related to that bug.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->find(1234);
|
|
|
$bug1234 = $bugsRowset->current();
|
|
|
@@ -634,40 +638,40 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
|
|
|
<para>
|
|
|
Alternatively, you can query rows from the destination table in a many-to-many
|
|
|
- relationship using a "magic method." <classname>Zend_Db_Table_Row_Abstract</classname> invokes the method:
|
|
|
- <methodname>findManyToManyRowset('<TableClass>', '<IntersectionTableClass>',
|
|
|
- '<Rule1>', '<Rule2>')</methodname> if you invoke a method matching any of the
|
|
|
- following patterns:
|
|
|
+ relationship using a "magic method." <classname>Zend_Db_Table_Row_Abstract</classname>
|
|
|
+ invokes the method: <code>findManyToManyRowset('<TableClass>',
|
|
|
+ '<IntersectionTableClass>', '<Rule1>', '<Rule2>')</code> if you invoke
|
|
|
+ a method matching any of the following patterns:
|
|
|
</para>
|
|
|
|
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->find<TableClass>Via<IntersectionTableClass>
|
|
|
- ([Zend_Db_Table_Select $select])</methodname>
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>
|
|
|
+ ([Zend_Db_Table_Select $select])</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>
|
|
|
- ([Zend_Db_Table_Select $select])</methodname>
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>
|
|
|
+ ([Zend_Db_Table_Select $select])</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
|
|
|
<listitem>
|
|
|
<para>
|
|
|
- <methodname>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>
|
|
|
- ([Zend_Db_Table_Select $select])</methodname>
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>
|
|
|
+ ([Zend_Db_Table_Select $select])</code>
|
|
|
</para>
|
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
|
|
|
|
<para>
|
|
|
- In the patterns above, <methodname><TableClass></methodname> and
|
|
|
- <methodname><IntersectionTableClass></methodname> are strings that correspond to the class
|
|
|
+ In the patterns above, <code><TableClass></code> and
|
|
|
+ <code><IntersectionTableClass></code> are strings that correspond to the class
|
|
|
names of the destination table and the intersection table, respectively.
|
|
|
- <methodname><Rule1></methodname> and <methodname><Rule2></methodname> are strings that correspond
|
|
|
+ <code><Rule1></code> and <code><Rule2></code> are strings that correspond
|
|
|
to the rule keys in the intersection table that reference the origin table and the
|
|
|
destination table, respectively.
|
|
|
</para>
|
|
|
@@ -690,7 +694,7 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
relationship representing products related to a given bug.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
|
$bugsRowset = $bugsTable->find(1234);
|
|
|
$bug1234 = $bugsRowset->current();
|
|
|
@@ -716,7 +720,7 @@ $products = $bug1234->findProductsViaBugsProductsByBug();
|
|
|
|
|
|
<para>
|
|
|
Declaring cascading operations in <classname>Zend_Db_Table</classname> is intended
|
|
|
- <emphasis>only</emphasis> for <acronym>RDBMS</acronym> brands that do not support
|
|
|
+ <emphasis>only</emphasis> for <acronym>RDBMS</acronym> brands that do not support
|
|
|
declarative referential integrity (DRI).
|
|
|
</para>
|
|
|
|
|
|
@@ -727,23 +731,25 @@ $products = $bug1234->findProductsViaBugsProductsByBug();
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- If your <acronym>RDBMS</acronym> implements DRI and the <methodname>ON DELETE</methodname> and
|
|
|
- <methodname>ON UPDATE</methodname> clauses, you should declare these clauses in your database
|
|
|
- schema, instead of using the cascading feature in <classname>Zend_Db_Table</classname>. Declaring
|
|
|
- cascading DRI rules in the <acronym>RDBMS</acronym> is better for database performance, consistency,
|
|
|
- and integrity.
|
|
|
+ If your <acronym>RDBMS</acronym> implements DRI and the <code>ON DELETE</code> and
|
|
|
+ <code>ON UPDATE</code> clauses, you should declare these clauses in your database
|
|
|
+ schema, instead of using the cascading feature in
|
|
|
+ <classname>Zend_Db_Table</classname>. Declaring cascading DRI rules in the
|
|
|
+ <acronym>RDBMS</acronym> is better for database performance, consistency, and
|
|
|
+ integrity.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- Most importantly, do not declare cascading operations both in the <acronym>RDBMS</acronym> and in your
|
|
|
- <classname>Zend_Db_Table</classname> class.
|
|
|
+ Most importantly, do not declare cascading operations both in the
|
|
|
+ <acronym>RDBMS</acronym> and in your <classname>Zend_Db_Table</classname> class.
|
|
|
</para>
|
|
|
|
|
|
</note>
|
|
|
|
|
|
<para>
|
|
|
You can declare cascading operations to execute against a dependent table when you
|
|
|
- apply an <methodname>UPDATE</methodname> or a <methodname>DELETE</methodname> to a row in a parent table.
|
|
|
+ apply an <constant>UPDATE</constant> or a <constant>DELETE</constant> to a row in a
|
|
|
+ parent table.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.cascading.example-delete">
|
|
|
@@ -751,11 +757,11 @@ $products = $bug1234->findProductsViaBugsProductsByBug();
|
|
|
<title>Example of a Cascading Delete</title>
|
|
|
|
|
|
<para>
|
|
|
- This example shows deleting a row in the <methodname>Products</methodname> table, which is
|
|
|
- configured to automatically delete dependent rows in the <methodname>Bugs</methodname> table.
|
|
|
+ This example shows deleting a row in the <code>Products</code> table, which is
|
|
|
+ configured to automatically delete dependent rows in the <code>Bugs</code> table.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
$productsTable = new Products();
|
|
|
$productsRowset = $productsTable->find(1234);
|
|
|
$product1234 = $productsRowset->current();
|
|
|
@@ -768,9 +774,10 @@ $product1234->delete();
|
|
|
</example>
|
|
|
|
|
|
<para>
|
|
|
- Similarly, if you use <methodname>UPDATE</methodname> to change the value of a primary key in a
|
|
|
- parent table, you may want the value in foreign keys of dependent tables to be updated
|
|
|
- automatically to match the new value, so that such references are kept up to date.
|
|
|
+ Similarly, if you use <constant>UPDATE</constant> to change the value of a primary key
|
|
|
+ in a parent table, you may want the value in foreign keys of dependent tables to be
|
|
|
+ updated automatically to match the new value, so that such references are kept up to
|
|
|
+ date.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
@@ -781,12 +788,12 @@ $product1234->delete();
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- To declare a cascading relationship in the <classname>Zend_Db_Table</classname>, edit the rules in the
|
|
|
- <methodname>$_referenceMap</methodname>. Set the associative array keys <methodname>'onDelete'</methodname> and
|
|
|
- <methodname>'onUpdate'</methodname> to the string 'cascade' (or the constant
|
|
|
- <methodname>self::CASCADE</methodname>). Before a row is deleted from the parent table, or its
|
|
|
- primary key values updated, any rows in the dependent table that refer to the parent's
|
|
|
- row are deleted or updated first.
|
|
|
+ To declare a cascading relationship in the <classname>Zend_Db_Table</classname>, edit
|
|
|
+ the rules in the <varname>$_referenceMap</varname>. Set the associative array keys
|
|
|
+ <code>'onDelete'</code> and <code>'onUpdate'</code> to the string 'cascade' (or the
|
|
|
+ constant <constant>self::CASCADE</constant>). Before a row is deleted from the parent
|
|
|
+ table, or its primary key values updated, any rows in the dependent table that refer to
|
|
|
+ the parent's row are deleted or updated first.
|
|
|
</para>
|
|
|
|
|
|
<example id="zend.db.table.relationships.cascading.example-declaration">
|
|
|
@@ -794,20 +801,20 @@ $product1234->delete();
|
|
|
<title>Example Declaration of Cascading Operations</title>
|
|
|
|
|
|
<para>
|
|
|
- In the example below, rows in the <methodname>Bugs</methodname> table are automatically deleted
|
|
|
- if the row in the <methodname>Products</methodname> table to which they refer is deleted. The
|
|
|
- <methodname>'onDelete'</methodname> element of the reference map entry is set to
|
|
|
- <methodname>self::CASCADE</methodname>.
|
|
|
+ In the example below, rows in the <code>Bugs</code> table are automatically deleted
|
|
|
+ if the row in the <code>Products</code> table to which they refer is deleted. The
|
|
|
+ <code>'onDelete'</code> element of the reference map entry is set to
|
|
|
+ <constant>self::CASCADE</constant>.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
No cascading update is done in the example below if the primary key value in the
|
|
|
- parent class is changed. The <methodname>'onUpdate'</methodname> element of the reference map
|
|
|
- entry is <methodname>self::RESTRICT</methodname>. You can get the same result by omitting
|
|
|
- the <methodname>'onUpdate'</methodname> entry.
|
|
|
+ parent class is changed. The <code>'onUpdate'</code> element of the reference map
|
|
|
+ entry is <constant>self::RESTRICT</constant>. You can get the same result by
|
|
|
+ omitting the <code>'onUpdate'</code> entry.
|
|
|
</para>
|
|
|
|
|
|
- <programlisting language="php"><![CDATA[
|
|
|
+ <programlisting language="php"><![CDATA[
|
|
|
class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
{
|
|
|
...
|
|
|
@@ -831,65 +838,67 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
<title>Notes Regarding Cascading Operations</title>
|
|
|
|
|
|
<para>
|
|
|
- <emphasis>Cascading operations invoked by <classname>Zend_Db_Table</classname> are not
|
|
|
- atomic.</emphasis>
|
|
|
+ <emphasis>Cascading operations invoked by <classname>Zend_Db_Table</classname> are
|
|
|
+ not atomic.</emphasis>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
This means that if your database implements and enforces referential integrity
|
|
|
- constraints, a cascading <methodname>UPDATE</methodname> executed by a <classname>Zend_Db_Table</classname> class
|
|
|
- conflicts with the constraint, and results in a referential integrity violation.
|
|
|
- You can use cascading <methodname>UPDATE</methodname> in <classname>Zend_Db_Table</classname>
|
|
|
+ constraints, a cascading <constant>UPDATE</constant> executed by a
|
|
|
+ <classname>Zend_Db_Table</classname> class conflicts with the constraint, and
|
|
|
+ results in a referential integrity violation. You can use cascading
|
|
|
+ <constant>UPDATE</constant> in <classname>Zend_Db_Table</classname>
|
|
|
<emphasis>only</emphasis> if your database does not enforce that referential
|
|
|
integrity constraint.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- Cascading <methodname>DELETE</methodname> suffers less from the problem of referential
|
|
|
+ Cascading <constant>DELETE</constant> suffers less from the problem of referential
|
|
|
integrity violations. You can delete dependent rows as a non-atomic action before
|
|
|
deleting the parent row that they reference.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- However, for both <methodname>UPDATE</methodname> and <methodname>DELETE</methodname>, changing the
|
|
|
- database in a non-atomic way also creates the risk that another database user can
|
|
|
- see the data in an inconsistent state. For example, if you delete a row and all its
|
|
|
- dependent rows, there is a small chance that another database client program can
|
|
|
- query the database after you have deleted the dependent rows, but before you delete
|
|
|
- the parent row. That client program may see the parent row with no dependent rows,
|
|
|
- and assume this is the intended state of the data. There is no way for that client
|
|
|
- to know that its query read the database in the middle of a change.
|
|
|
+ However, for both <constant>UPDATE</constant> and <constant>DELETE</constant>,
|
|
|
+ changing the database in a non-atomic way also creates the risk that another
|
|
|
+ database user can see the data in an inconsistent state. For example, if you delete
|
|
|
+ a row and all its dependent rows, there is a small chance that another database
|
|
|
+ client program can query the database after you have deleted the dependent rows, but
|
|
|
+ before you delete the parent row. That client program may see the parent row with no
|
|
|
+ dependent rows, and assume this is the intended state of the data. There is no way
|
|
|
+ for that client to know that its query read the database in the middle of a change.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
The issue of non-atomic change can be mitigated by using transactions to isolate
|
|
|
- your change. But some RDBMS brands don't support transactions, or allow clients to
|
|
|
- read "dirty" changes that have not been committed yet.
|
|
|
+ your change. But some <acronym>RDBMS</acronym> brands don't support transactions, or
|
|
|
+ allow clients to read "dirty" changes that have not been committed yet.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- <emphasis>Cascading operations in <classname>Zend_Db_Table</classname> are invoked only by
|
|
|
- <classname>Zend_Db_Table</classname>.</emphasis>
|
|
|
+ <emphasis>Cascading operations in <classname>Zend_Db_Table</classname> are invoked
|
|
|
+ only by <classname>Zend_Db_Table</classname>.</emphasis>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- Cascading deletes and updates defined in your <classname>Zend_Db_Table</classname> classes are applied if
|
|
|
- you execute the <methodname>save()</methodname> or <methodname>delete()</methodname> methods on the Row
|
|
|
- class. However, if you update or delete data using another interface, such as a
|
|
|
- query tool or another application, the cascading operations are not applied. Even
|
|
|
- when using <methodname>update()</methodname> and <methodname>delete()</methodname> methods in the
|
|
|
- <classname>Zend_Db_Adapter</classname> class, cascading operations defined in your <classname>Zend_Db_Table</classname> classes
|
|
|
- are not executed.
|
|
|
+ Cascading deletes and updates defined in your <classname>Zend_Db_Table</classname>
|
|
|
+ classes are applied if you execute the <methodname>save()</methodname> or
|
|
|
+ <methodname>delete()</methodname> methods on the Row class. However, if you update
|
|
|
+ or delete data using another interface, such as a query tool or another application,
|
|
|
+ the cascading operations are not applied. Even when using
|
|
|
+ <methodname>update()</methodname> and <methodname>delete()</methodname> methods
|
|
|
+ in the <classname>Zend_Db_Adapter</classname> class, cascading operations defined in
|
|
|
+ your <classname>Zend_Db_Table</classname> classes are not executed.
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- <emphasis>No Cascading <methodname>INSERT</methodname>.</emphasis>
|
|
|
+ <emphasis>No Cascading <constant>INSERT</constant>.</emphasis>
|
|
|
</para>
|
|
|
|
|
|
<para>
|
|
|
- There is no support for a cascading <methodname>INSERT</methodname>. You must insert a row to a
|
|
|
- parent table in one operation, and insert row(s) to a dependent table in a separate
|
|
|
- operation.
|
|
|
+ There is no support for a cascading <constant>INSERT</constant>. You must insert a
|
|
|
+ row to a parent table in one operation, and insert row(s) to a dependent table in a
|
|
|
+ separate operation.
|
|
|
</para>
|
|
|
|
|
|
</sect3>
|