|
@@ -1,5 +1,5 @@
|
|
|
-<?xml version="1.0" encoding="utf-8"?>
|
|
|
|
|
-<!-- EN-Revision: 13846 -->
|
|
|
|
|
|
|
+<?xml version="1.0" encoding="UTF-8"?>
|
|
|
|
|
+<!-- EN-Revision: 15346 -->
|
|
|
<!-- Reviewed: no -->
|
|
<!-- Reviewed: no -->
|
|
|
<sect1 id="zend.db.table.relationships">
|
|
<sect1 id="zend.db.table.relationships">
|
|
|
<title>Relations Zend_Db_Table</title>
|
|
<title>Relations Zend_Db_Table</title>
|
|
@@ -7,22 +7,30 @@
|
|
|
<sect2 id="zend.db.table.relationships.introduction">
|
|
<sect2 id="zend.db.table.relationships.introduction">
|
|
|
<title>Introduction</title>
|
|
<title>Introduction</title>
|
|
|
|
|
|
|
|
- <para>Les tables possèdent des relations entre elles, dans une base de données relationnelle. Une entité d'une
|
|
|
|
|
- table peut être liée à une autre entité d'une autre table, via un procédé appelé contrainte d'intégrité
|
|
|
|
|
- référentielle</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les tables possèdent des relations entre elles, dans une base de données
|
|
|
|
|
+ relationnelle. Une entité d'une table peut être liée à une autre entité d'une autre
|
|
|
|
|
+ table, via un procédé appelé contrainte d'intégrité référentielle
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>La classe <classname>Zend_Db_Table_Row</classname> possède des méthodes pour récupérer des enregistrement dans
|
|
|
|
|
- d'autres tables, liées à celle en cours.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ La classe <classname>Zend_Db_Table_Row</classname> possède des méthodes pour
|
|
|
|
|
+ récupérer des enregistrement dans d'autres tables, liées à celle en cours.
|
|
|
|
|
+ </para>
|
|
|
</sect2>
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="zend.db.table.relationships.defining">
|
|
<sect2 id="zend.db.table.relationships.defining">
|
|
|
<title>Définir ses relations</title>
|
|
<title>Définir ses relations</title>
|
|
|
|
|
|
|
|
- <para>Chaque table doit avoir sa classe étendant <classname>Zend_Db_Table_Abstract</classname>, comme décrit dans <xref
|
|
|
|
|
- linkend="zend.db.table.defining" />. Voyez aussi <xref linkend="zend.db.adapter.example-database" /> pour une
|
|
|
|
|
- description de la base de donnée qui servira d'exemple pour la suite de ce chapitre.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Chaque table doit avoir sa classe étendant
|
|
|
|
|
+ <classname>Zend_Db_Table_Abstract</classname>, comme décrit dans <xref
|
|
|
|
|
+ linkend="zend.db.table.defining" />. Voyez aussi <xref
|
|
|
|
|
+ linkend="zend.db.adapter.example-database" /> pour une description de la base de donnée
|
|
|
|
|
+ qui servira d'exemple pour la suite de ce chapitre.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Voici les classes correspondantes à ces tables :</para>
|
|
|
|
|
|
|
+ <para>Voici les classes correspondantes à ces tables :</para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
class Accounts extends Zend_Db_Table_Abstract
|
|
class Accounts extends Zend_Db_Table_Abstract
|
|
@@ -82,73 +90,115 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
}
|
|
}
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
- <para>Si vous utilisez <classname>Zend_Db_Table</classname> pour émuler les cascades <code>UPDATE</code> et
|
|
|
|
|
- <code>DELETE</code>, alors déclarez <code>$_dependentTables</code> en tant que tableau dans la classe des tables
|
|
|
|
|
- parentes. Listez ainsi le nom de chaque table dépendante. Utilisez bien le nom des classes, et non les noms
|
|
|
|
|
- physiques des tables.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous utilisez <classname>Zend_Db_Table</classname> pour émuler les cascades
|
|
|
|
|
+ <code>UPDATE</code> et <code>DELETE</code>, alors déclarez
|
|
|
|
|
+ <code>$_dependentTables</code> en tant que tableau dans la classe des tables parentes.
|
|
|
|
|
+ Listez ainsi le nom de chaque table dépendante. Utilisez bien le nom des classes, et non
|
|
|
|
|
+ les noms physiques des tables.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<note>
|
|
<note>
|
|
|
- <para>Si votre SGBD implémente le mécanisme des cascades, alors vous n'avez pas besoin de déclarer
|
|
|
|
|
- <code>$_dependentTables</code>. Voyez <xref linkend="zend.db.table.relationships.cascading" /> pour plus
|
|
|
|
|
- d'informations.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si votre SGBD implémente le mécanisme des cascades, alors vous n'avez pas
|
|
|
|
|
+ besoin de déclarer <code>$_dependentTables</code>. Voyez <xref
|
|
|
|
|
+ linkend="zend.db.table.relationships.cascading" /> pour plus d'informations.
|
|
|
|
|
+ </para>
|
|
|
</note>
|
|
</note>
|
|
|
|
|
|
|
|
- <para>Déclarez un tableau <code>$_referenceMap</code> dans les classes de chaque table dépendante (qui "reçoit
|
|
|
|
|
- une clé"). C'est un tableau associatif, dit de "rôles". Un rôle définit quelle table est parente dans la
|
|
|
|
|
- relation, et quelle est sa colonne de parenté.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Le rôle est utilisé comme index du tableau <code>$_referenceMap</code>. Il est utilisé pour définir la
|
|
|
|
|
- relation, et pourra faire partie du nom de certaines méthodes, comme nous le verrons plus tard. Choisissez ainsi
|
|
|
|
|
- un nom de rôle de manière intelligente.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Dans l'exemple du dessus, les rôles dans la classe Bugs sont : <code>"Reporter"</code>,
|
|
|
|
|
- <code>"Engineer"</code>, <code>"Verifier"</code> et <code>"Product"</code>.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>La valeur de chaque rôle dans le tableau <code>$_referenceMap</code> est aussi un tableau associatif. Les
|
|
|
|
|
- éléments de chaque rôle sont décrits ci-après.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Déclarez un tableau <code>$_referenceMap</code> dans les classes de chaque table
|
|
|
|
|
+ dépendante (qui "reçoit une clé"). C'est un tableau associatif, dit de "rôles". Un rôle
|
|
|
|
|
+ définit quelle table est parente dans la relation, et quelle est sa colonne de
|
|
|
|
|
+ parenté.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le rôle est utilisé comme index du tableau <code>$_referenceMap</code>. Il est
|
|
|
|
|
+ utilisé pour définir la relation, et pourra faire partie du nom de certaines méthodes,
|
|
|
|
|
+ comme nous le verrons plus tard. Choisissez ainsi un nom de rôle de manière
|
|
|
|
|
+ intelligente.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans l'exemple du dessus, les rôles dans la classe Bugs sont :
|
|
|
|
|
+ <code>"Reporter"</code>, <code>"Engineer"</code>, <code>"Verifier"</code> et
|
|
|
|
|
+ <code>"Product"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ La valeur de chaque rôle dans le tableau <code>$_referenceMap</code> est aussi un
|
|
|
|
|
+ tableau associatif. Les éléments de chaque rôle sont décrits ci-après.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><emphasis>columns</emphasis> => une chaîne de caractères ou un tableau de chaînes
|
|
|
|
|
- désignant le(s) nom(s) des clés étrangères dans la table dépendante (la table actuelle donc).</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Il est courant qu'il s'agisse d'une seule colonne, mais on peut rencontrer le cas de clés
|
|
|
|
|
- composées de multiples colonnes.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>columns</emphasis> => une chaîne de caractères ou un tableau
|
|
|
|
|
+ de chaînes désignant le(s) nom(s) des clés étrangères dans la table dépendante
|
|
|
|
|
+ (la table actuelle donc).
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Il est courant qu'il s'agisse d'une seule colonne, mais on peut rencontrer
|
|
|
|
|
+ le cas de clés composées de multiples colonnes.
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><emphasis>refTableClass</emphasis> => désigne la classe de la table parente, liée
|
|
|
|
|
- à cette colonne. Utilisez le nom de la classe et non le nom de la table physique.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Il est courant qu'une table dépendante n'ait qu'une seule référence d'une même table parente.
|
|
|
|
|
- Cependant certaines tables peuvent avoir plusieurs références vers une même table parente. Dans notre
|
|
|
|
|
- base de données d'exemple, c'est le cas avec la table <code>bugs</code>. Elle possède soit une et une
|
|
|
|
|
- seule colonne référençant la table parente <code>products</code>, mais elle possède trois références
|
|
|
|
|
- (donc trois colonnes) vers la table parente <code>accounts</code>. Chaque référence doit être
|
|
|
|
|
- matérialisée par un rôle unique dans le tableau <code>$_referenceMap</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>refTableClass</emphasis> => désigne la classe de la table
|
|
|
|
|
+ parente, liée à cette colonne. Utilisez le nom de la classe et non le nom de la
|
|
|
|
|
+ table physique.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Il est courant qu'une table dépendante n'ait qu'une seule référence d'une
|
|
|
|
|
+ même table parente. Cependant certaines tables peuvent avoir plusieurs
|
|
|
|
|
+ références vers une même table parente. Dans notre base de données d'exemple,
|
|
|
|
|
+ c'est le cas avec la table <code>bugs</code>. Elle possède soit une et une seule
|
|
|
|
|
+ colonne référençant la table parente <code>products</code>, mais elle possède
|
|
|
|
|
+ trois références (donc trois colonnes) vers la table parente
|
|
|
|
|
+ <code>accounts</code>. Chaque référence doit être matérialisée par un rôle
|
|
|
|
|
+ unique dans le tableau <code>$_referenceMap</code>.
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><emphasis>refColumns</emphasis> => c'est une chaîne de caractères ou un tableau
|
|
|
|
|
- de chaînes nommant la(es) colonne(s) (clé primaire) de la table parente.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Si vous devez utiliser de multiples colonnes parentes pour une seule clé, alors veillez à bien les
|
|
|
|
|
- entrer dans <code>'columns'</code> dans le même ordre que dans <code>'refColumns'</code>.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Il est optionnel de spécifier la <code>refColumns</code>. La clé primaire est utilisée par défaut
|
|
|
|
|
- comme colonne parente dans une relation.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>refColumns</emphasis> => c'est une chaîne de caractères ou un
|
|
|
|
|
+ tableau de chaînes nommant la(es) colonne(s) (clé primaire) de la table
|
|
|
|
|
+ parente.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous devez utiliser de multiples colonnes parentes pour une seule clé,
|
|
|
|
|
+ alors veillez à bien les entrer dans <code>'columns'</code> dans le même ordre
|
|
|
|
|
+ que dans <code>'refColumns'</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Il est optionnel de spécifier la <code>refColumns</code>. La clé primaire
|
|
|
|
|
+ est utilisée par défaut comme colonne parente dans une relation.
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><emphasis>onDelete</emphasis> => le nom de l'action à exécuter si un
|
|
|
|
|
- enregistrement est supprimé de la table parente. Voyez <xref
|
|
|
|
|
- linkend="zend.db.table.relationships.cascading" /> pour plus d'informations.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>onDelete</emphasis> => le nom de l'action à exécuter si un
|
|
|
|
|
+ enregistrement est supprimé de la table parente. Voyez <xref
|
|
|
|
|
+ linkend="zend.db.table.relationships.cascading" /> pour plus
|
|
|
|
|
+ d'informations.
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><emphasis>onUpdate</emphasis> => le nom de l'action à exécuter si un
|
|
|
|
|
- enregistrement est mis à jour dans la table parente. Voyez<xref
|
|
|
|
|
- linkend="zend.db.table.relationships.cascading" /> pour plus d'informations.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>onUpdate</emphasis> => le nom de l'action à exécuter si un
|
|
|
|
|
+ enregistrement est mis à jour dans la table parente. Voyez<xref
|
|
|
|
|
+ linkend="zend.db.table.relationships.cascading" /> pour plus
|
|
|
|
|
+ d'informations.
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
</itemizedlist>
|
|
|
</sect2>
|
|
</sect2>
|
|
@@ -156,26 +206,37 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
<sect2 id="zend.db.table.relationships.fetching.dependent">
|
|
<sect2 id="zend.db.table.relationships.fetching.dependent">
|
|
|
<title>Récupérer des enregistrements dépendants (enfants)</title>
|
|
<title>Récupérer des enregistrements dépendants (enfants)</title>
|
|
|
|
|
|
|
|
- <para>Si vous possédez un enregistrement actif (<code>Row</code>), il est possible de récupérer ses enfants
|
|
|
|
|
- dépendants, si les dépendances ont été déclarées suivant la procédure ci-dessus. Utilisez la méthode :</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous possédez un enregistrement actif (<code>Row</code>), il est possible de
|
|
|
|
|
+ récupérer ses enfants dépendants, si les dépendances ont été déclarées suivant la
|
|
|
|
|
+ procédure ci-dessus. Utilisez la méthode :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$row->findDependentRowset($table, [$rule]);
|
|
$row->findDependentRowset($table, [$rule]);
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
- <para>Cette méthode retourne un objet instance de <classname>Zend_Db_Table_Rowset_Abstract</classname>, qui contient tous
|
|
|
|
|
- les enregistrements (<code>Row</code>) de la table dépendante <code>$table</code> faisant référence à
|
|
|
|
|
- l'enregistrement actif actuel <code>$row</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cette méthode retourne un objet instance de
|
|
|
|
|
+ <classname>Zend_Db_Table_Rowset_Abstract</classname>, qui contient tous les
|
|
|
|
|
+ enregistrements (<code>Row</code>) de la table dépendante <code>$table</code> faisant
|
|
|
|
|
+ référence à l'enregistrement actif actuel <code>$row</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Le paramètre <code>$table</code> désigne la table dépendante à utiliser. Ceci peut être une chaîne de
|
|
|
|
|
- caractères aussi bien qu'un objet de la classe de cette table.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le paramètre <code>$table</code> désigne la table dépendante à utiliser. Ceci peut
|
|
|
|
|
+ être une chaîne de caractères aussi bien qu'un objet de la classe de cette table.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.dependent.example">
|
|
<example id="zend.db.table.relationships.fetching.dependent.example">
|
|
|
<title>Récupérer des enregistrements dépendants</title>
|
|
<title>Récupérer des enregistrements dépendants</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple montre comment obtenir un enregistrement actif (objet <code>Row</code>) de la table
|
|
|
|
|
- <code>Accounts</code>, et comment en récupérer les enfants dépendants de la table <code>Bugs</code>. (les
|
|
|
|
|
- bugs reportés par ce compte)</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple montre comment obtenir un enregistrement actif (objet
|
|
|
|
|
+ <code>Row</code>) de la table <code>Accounts</code>, et comment en récupérer les
|
|
|
|
|
+ enfants dépendants de la table <code>Bugs</code>. (les bugs reportés par ce
|
|
|
|
|
+ compte)
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
$accountsTable = new Accounts();
|
|
@@ -186,19 +247,27 @@ $bugsReportedByUser = $user1234->findDependentRowset('Bugs');
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Le second paramètre <code>$rule</code> est optionnel. Il s'agit du nom du rôle à utiliser depuis le
|
|
|
|
|
- tableau <code>$_referenceMap</code> de la classe de la table dépendante. Si vous ne le spécifiez pas, le premier
|
|
|
|
|
- rôle sera utilisé. Il n'y a dans la majorité des cas qu'un seul rôle.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le second paramètre <code>$rule</code> est optionnel. Il s'agit du nom du rôle à
|
|
|
|
|
+ utiliser depuis le tableau <code>$_referenceMap</code> de la classe de la table
|
|
|
|
|
+ dépendante. Si vous ne le spécifiez pas, le premier rôle sera utilisé. Il n'y a dans la
|
|
|
|
|
+ majorité des cas qu'un seul rôle.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Dans l'exemple ci dessus, nous ne fournissons pas de nom de rôle, le premier est donc pris en
|
|
|
|
|
- considération, et il s'agit de <code>"Reporter"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans l'exemple ci dessus, nous ne fournissons pas de nom de rôle, le premier est
|
|
|
|
|
+ donc pris en considération, et il s'agit de <code>"Reporter"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.dependent.example-by">
|
|
<example id="zend.db.table.relationships.fetching.dependent.example-by">
|
|
|
<title>Récupérer des enregistrements dépendants avec un rôle spécifique</title>
|
|
<title>Récupérer des enregistrements dépendants avec un rôle spécifique</title>
|
|
|
|
|
|
|
|
- <para>Dans cet exemple nous montrons comment obtenir un enregistrement (<code>Row</code>) depuis la table
|
|
|
|
|
- <code>Accounts</code>, et comment trouver les <code>Bugs</code> assignés à ce compte (<code>Account</code>).
|
|
|
|
|
- Nous devrons alors nommer le rôle <code>"Engineer"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans cet exemple nous montrons comment obtenir un enregistrement
|
|
|
|
|
+ (<code>Row</code>) depuis la table <code>Accounts</code>, et comment trouver les
|
|
|
|
|
+ <code>Bugs</code> assignés à ce compte (<code>Account</code>). Nous devrons alors
|
|
|
|
|
+ nommer le rôle <code>"Engineer"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
$accountsTable = new Accounts();
|
|
@@ -210,17 +279,25 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Vous pouvez rajouter des critères à vos relations, comme l'ordre ou la limite, ceci en utilisant l'objet
|
|
|
|
|
- <code>select</code> de l'enregistrement parent.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para><example id="zend.db.table.relationships.fetching.dependent.example-by-select">
|
|
|
|
|
- <title>Récupérer des enregistrements dépendants en utilisant un objet
|
|
|
|
|
- <classname>Zend_Db_Table_Select</classname></title>
|
|
|
|
|
-
|
|
|
|
|
- <para>Dans cet exemple nous montrons comment obtenir un enregistrement (<code>Row</code>) depuis la
|
|
|
|
|
- table <code>Accounts</code>, et comment trouver les <code>Bugs</code> assignés à ce compte
|
|
|
|
|
- (<code>Account</code>), mais limités seulement à trois enregistrements, et ordonnés par nom. Nous
|
|
|
|
|
- devrons nommer le rôle <code>"Engineer"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Vous pouvez rajouter des critères à vos relations, comme l'ordre ou la limite,
|
|
|
|
|
+ ceci en utilisant l'objet <code>select</code> de l'enregistrement parent.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <example id="zend.db.table.relationships.fetching.dependent.example-by-select">
|
|
|
|
|
+ <title>
|
|
|
|
|
+ Récupérer des enregistrements dépendants en utilisant un objet
|
|
|
|
|
+ Zend_Db_Table_Select
|
|
|
|
|
+ </title>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans cet exemple nous montrons comment obtenir un enregistrement
|
|
|
|
|
+ (<code>Row</code>) depuis la table <code>Accounts</code>, et comment trouver les
|
|
|
|
|
+ <code>Bugs</code> assignés à ce compte (<code>Account</code>), mais limités
|
|
|
|
|
+ seulement à trois enregistrements, et ordonnés par nom. Nous devrons nommer le
|
|
|
|
|
+ rôle <code>"Engineer"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
$accountsTable = new Accounts();
|
|
@@ -233,10 +310,12 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
'Engineer',
|
|
'Engineer',
|
|
|
$select);
|
|
$select);
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
- </example>Vous pouvez récupérer les enregistrements dépendants d'une autre manière. En utilisant les
|
|
|
|
|
- "méthodes magiques". En effet, <classname>Zend_Db_Table_Row_Abstract</classname> va utiliser la méthode
|
|
|
|
|
- <code>findDependentRowset('<TableClass>', '<Rule>')</code> si vous appelez sur l'enregistrement une
|
|
|
|
|
- méthode correspondante à un de ces motifs :</para>
|
|
|
|
|
|
|
+ </example>Vous pouvez récupérer les enregistrements dépendants d'une autre manière.
|
|
|
|
|
+ En utilisant les "méthodes magiques". En effet,
|
|
|
|
|
+ <classname>Zend_Db_Table_Row_Abstract</classname> va utiliser la méthode
|
|
|
|
|
+ <code>findDependentRowset('<TableClass>', '<Rule>')</code> si vous appelez
|
|
|
|
|
+ sur l'enregistrement une méthode correspondante à un de ces motifs :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
<listitem>
|
|
@@ -248,21 +327,32 @@ $bugsAssignedToUser = $user1234->findDependentRowset('Bugs',
|
|
|
</listitem>
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
- <para>Dans les motifs ci-dessus, <code><TableClass></code> et <code><Rule></code> désignent
|
|
|
|
|
- respectivement le nom de la table dépendante et le rôle à utiliser.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans les motifs ci-dessus, <code><TableClass></code> et
|
|
|
|
|
+ <code><Rule></code> désignent respectivement le nom de la table dépendante et le
|
|
|
|
|
+ rôle à utiliser.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<note>
|
|
<note>
|
|
|
- <para>Certains frameworks tels que Rails pour Ruby, utilise un mécanisme dit d'inflexion, qui permet de
|
|
|
|
|
- transformer les noms des identifiants (nom de table, de rôle...) d'une certaine manière bien spécifique dans
|
|
|
|
|
- les méthodes appelées. Cela n'est pas le cas de Zend Framework : vous devez, dans vos méthodes magiques,
|
|
|
|
|
- utiliser l'orthographe exacte des noms des rôles et classes, tels que vous les définissez.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Certains frameworks tels que Rails pour Ruby, utilise un mécanisme dit
|
|
|
|
|
+ d'inflexion, qui permet de transformer les noms des identifiants (nom de table, de
|
|
|
|
|
+ rôle...) d'une certaine manière bien spécifique dans les méthodes appelées. Cela
|
|
|
|
|
+ n'est pas le cas de Zend Framework : vous devez, dans vos méthodes magiques,
|
|
|
|
|
+ utiliser l'orthographe exacte des noms des rôles et classes, tels que vous les
|
|
|
|
|
+ définissez.
|
|
|
|
|
+ </para>
|
|
|
</note>
|
|
</note>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.dependent.example-magic">
|
|
<example id="zend.db.table.relationships.fetching.dependent.example-magic">
|
|
|
- <title>Récupérer des enregistrements dépendants en utilisant les méthodes magiques</title>
|
|
|
|
|
|
|
+ <title>
|
|
|
|
|
+ Récupérer des enregistrements dépendants en utilisant les méthodes magiques
|
|
|
|
|
+ </title>
|
|
|
|
|
|
|
|
- <para>Cet exemple a le même effet que le précédent. Il utilise simplement les méthodes magiques pour
|
|
|
|
|
- récupérer les enregistrements dépendants.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple a le même effet que le précédent. Il utilise simplement les
|
|
|
|
|
+ méthodes magiques pour récupérer les enregistrements dépendants.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$accountsTable = new Accounts();
|
|
$accountsTable = new Accounts();
|
|
@@ -281,25 +371,36 @@ $bugsAssignedTo = $user1234->findBugsByEngineer();
|
|
|
<sect2 id="zend.db.table.relationships.fetching.parent">
|
|
<sect2 id="zend.db.table.relationships.fetching.parent">
|
|
|
<title>Récupérer l'enregistrement parent</title>
|
|
<title>Récupérer l'enregistrement parent</title>
|
|
|
|
|
|
|
|
- <para>Si vous possédez un enregistrement (<code>Row</code>) dont la table possède une table parente, il est
|
|
|
|
|
- possible alors de récupérer l'enregistrement parent. Utilisez pour cela la méthode :</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous possédez un enregistrement (<code>Row</code>) dont la table possède une
|
|
|
|
|
+ table parente, il est possible alors de récupérer l'enregistrement parent. Utilisez pour
|
|
|
|
|
+ cela la méthode :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$row->findParentRow($table, [$rule]);
|
|
$row->findParentRow($table, [$rule]);
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
- <para>La logique veut qu'il ne puisse y avoir qu'un et un seul parent par enregistrement. Ainsi, cette méthode
|
|
|
|
|
- retourne un objet <code>Row</code> et non un objet <code>Rowset</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ La logique veut qu'il ne puisse y avoir qu'un et un seul parent par
|
|
|
|
|
+ enregistrement. Ainsi, cette méthode retourne un objet <code>Row</code> et non un objet
|
|
|
|
|
+ <code>Rowset</code>
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Le premier paramètre <code>$table</code> désigne la table parente. Ceci peut être une chaîne de
|
|
|
|
|
- caractères, ou un objet instance de la classe de la table parente.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le premier paramètre <code>$table</code> désigne la table parente. Ceci peut être
|
|
|
|
|
+ une chaîne de caractères, ou un objet instance de la classe de la table parente.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.parent.example">
|
|
<example id="zend.db.table.relationships.fetching.parent.example">
|
|
|
<title>Récupérer l'enregistrement parent</title>
|
|
<title>Récupérer l'enregistrement parent</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple illustre la récupération d'un enregistrement <code>Bugs</code> ( disons par exemple ceux
|
|
|
|
|
- avec le statut "NEW"), et l'obtention de l'enregistrement parent correspondant à <code>Accounts</code> (la
|
|
|
|
|
- personne ayant reporté le bug)</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple illustre la récupération d'un enregistrement <code>Bugs</code> (disons
|
|
|
|
|
+ par exemple ceux avec le statut "NEW"), et l'obtention de l'enregistrement
|
|
|
|
|
+ parent correspondant à <code>Accounts</code> (la personne ayant reporté le
|
|
|
|
|
+ bug)
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -310,18 +411,26 @@ $reporter = $bug1->findParentRow('Accounts');
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Le second paramètre <code>$rule</code> est optionnel. Il s'agit du nom du rôle à utiliser depuis le
|
|
|
|
|
- tableau <code>$_referenceMap</code> de la classe de la table dépendante. Si vous ne le spécifiez pas, le premier
|
|
|
|
|
- rôle sera utilisé. Il n'y a dans la majorité des cas qu'un seul rôle.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le second paramètre <code>$rule</code> est optionnel. Il s'agit du nom du rôle à
|
|
|
|
|
+ utiliser depuis le tableau <code>$_referenceMap</code> de la classe de la table
|
|
|
|
|
+ dépendante. Si vous ne le spécifiez pas, le premier rôle sera utilisé. Il n'y a dans la
|
|
|
|
|
+ majorité des cas qu'un seul rôle.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Dans l'exemple ci dessus, nous ne fournissons pas de nom de rôle, le premier est donc pris en
|
|
|
|
|
- considération, et il s'agit de <code>"Reporter"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans l'exemple ci dessus, nous ne fournissons pas de nom de rôle, le premier est
|
|
|
|
|
+ donc pris en considération, et il s'agit de <code>"Reporter"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.parent.example-by">
|
|
<example id="zend.db.table.relationships.fetching.parent.example-by">
|
|
|
<title>Récupérer un enregistrement parent avec un rôle spécifique</title>
|
|
<title>Récupérer un enregistrement parent avec un rôle spécifique</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple va démontrer comment, à partir d'un enregistrement de <code>Bugs</code>, récupérer la
|
|
|
|
|
- personne en étant assignée. Il va falloir utiliser le rôle <code>"Engineer"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple va démontrer comment, à partir d'un enregistrement de
|
|
|
|
|
+ <code>Bugs</code>, récupérer la personne en étant assignée. Il va falloir utiliser
|
|
|
|
|
+ le rôle <code>"Engineer"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -332,35 +441,49 @@ $engineer = $bug1->findParentRow('Accounts', 'Engineer');
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Vous pouvez récupérer l'enregistrement parent d'une autre manière. En utilisant les "méthodes magiques".
|
|
|
|
|
- En effet, Zend_Db_Table_Row_Abstract va utiliser la méthode<code>findParentRow('<TableClass>',
|
|
|
|
|
- '<Rule>')</code> si vous appelez sur l'enregistrement une méthode correspondante à un de ces motifs
|
|
|
|
|
- :</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Vous pouvez récupérer l'enregistrement parent d'une autre manière. En utilisant
|
|
|
|
|
+ les "méthodes magiques". En effet, Zend_Db_Table_Row_Abstract va utiliser la
|
|
|
|
|
+ méthode<code>findParentRow('<TableClass>', '<Rule>')</code> si vous appelez
|
|
|
|
|
+ sur l'enregistrement une méthode correspondante à un de ces motifs :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><code>$row->findParent<TableClass>([Zend_Db_Table_Select $select])</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$row->findParent<TableClass>([Zend_Db_Table_Select
|
|
|
|
|
+ $select])</code>
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><code>$row->findParent<TableClass>By<Rule>([Zend_Db_Table_Select
|
|
|
|
|
- $select])</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$row->findParent<TableClass>By<Rule>([Zend_Db_Table_Select
|
|
|
|
|
+ $select])</code>
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
- <para>Dans les motifs ci-dessus, <code><TableClass></code> et <code><Rule></code> représentent
|
|
|
|
|
- respectivement le nom de la classe de la table parente, et le rôle à utiliser éventuellement.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans les motifs ci-dessus, <code><TableClass></code> et
|
|
|
|
|
+ <code><Rule></code> représentent respectivement le nom de la classe de la table
|
|
|
|
|
+ parente, et le rôle à utiliser éventuellement.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<note>
|
|
<note>
|
|
|
- <para>Les noms de la table et du rôle doivent être orthographiés de la même manière qu'ils ne le sont lors
|
|
|
|
|
- de leur définition dans la table.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les noms de la table et du rôle doivent être orthographiés de la même manière
|
|
|
|
|
+ qu'ils ne le sont lors de leur définition dans la table.
|
|
|
|
|
+ </para>
|
|
|
</note>
|
|
</note>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.parent.example-magic">
|
|
<example id="zend.db.table.relationships.fetching.parent.example-magic">
|
|
|
<title>Récupérer un enregistrement parent en utilisant les méthodes magiques</title>
|
|
<title>Récupérer un enregistrement parent en utilisant les méthodes magiques</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple a le même effet que le précédent. Il utilise simplement les méthodes magiques pour
|
|
|
|
|
- récupérer l'enregistrement parent.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple a le même effet que le précédent. Il utilise simplement les
|
|
|
|
|
+ méthodes magiques pour récupérer l'enregistrement parent.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -377,11 +500,17 @@ $engineer = $bug1->findParentAccountsByEngineer();
|
|
|
</sect2>
|
|
</sect2>
|
|
|
|
|
|
|
|
<sect2 id="zend.db.table.relationships.fetching.many-to-many">
|
|
<sect2 id="zend.db.table.relationships.fetching.many-to-many">
|
|
|
- <title>Récupérer des enregistrements dans une relation N-N (plusieurs-à-plusieurs ou "many-to-many")</title>
|
|
|
|
|
-
|
|
|
|
|
- <para>Si vous possédez un enregistrement sur une table (appelons la "table d'origine") ayant une relation
|
|
|
|
|
- plusieurs à plusieurs vers une autre table (appelons la "table de destination"), vous pouvez alors accéder aux
|
|
|
|
|
- enregistrements de la table de destination, via une table dite "d'intersection". Utilisez la méthode :</para>
|
|
|
|
|
|
|
+ <title>
|
|
|
|
|
+ Récupérer des enregistrements dans une relation N-N (plusieurs-à-plusieurs ou
|
|
|
|
|
+ "many-to-many")
|
|
|
|
|
+ </title>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous possédez un enregistrement sur une table (appelons la "table d'origine")
|
|
|
|
|
+ ayant une relation plusieurs à plusieurs vers une autre table (appelons la "table de
|
|
|
|
|
+ destination"), vous pouvez alors accéder aux enregistrements de la table de destination,
|
|
|
|
|
+ via une table dite "d'intersection". Utilisez la méthode :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$row->findManyToManyRowset($table,
|
|
$row->findManyToManyRowset($table,
|
|
@@ -391,23 +520,36 @@ $row->findManyToManyRowset($table,
|
|
|
[Zend_Db_Table_Select $select]]]);
|
|
[Zend_Db_Table_Select $select]]]);
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
|
|
|
|
|
- <para>Cette méthode retourne un objet instance de <classname>Zend_Db_Table_Rowset_Abstract</classname> qui contient les
|
|
|
|
|
- enregistrements de la table <code>$table</code> qui correspondent à la relation plusieurs à plusieurs.
|
|
|
|
|
- L'enregistrement courant de la table courante, <code>$row</code>, est utilisé comme point de départ pour
|
|
|
|
|
- effectuer une jointure vers la table de destination, via la table d'intersection.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Le premier paramètre <code>$table</code> peut être soit une chaîne soit un objet instance de la classe de
|
|
|
|
|
- la table de destination dans la relation plusieurs à plusieurs.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Le second paramètre <code>$intersectionTable</code> peut être soit une chaîne soit un objet instance de la
|
|
|
|
|
- classe de la table d'intersection dans la relation plusieurs à plusieurs.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cette méthode retourne un objet instance de
|
|
|
|
|
+ <classname>Zend_Db_Table_Rowset_Abstract</classname> qui contient les enregistrements de
|
|
|
|
|
+ la table <code>$table</code> qui correspondent à la relation plusieurs à plusieurs.
|
|
|
|
|
+ L'enregistrement courant de la table courante, <code>$row</code>, est utilisé comme
|
|
|
|
|
+ point de départ pour effectuer une jointure vers la table de destination, via la table
|
|
|
|
|
+ d'intersection.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le premier paramètre <code>$table</code> peut être soit une chaîne soit un objet
|
|
|
|
|
+ instance de la classe de la table de destination dans la relation plusieurs à
|
|
|
|
|
+ plusieurs.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le second paramètre <code>$intersectionTable</code> peut être soit une chaîne soit
|
|
|
|
|
+ un objet instance de la classe de la table d'intersection dans la relation plusieurs à
|
|
|
|
|
+ plusieurs.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example">
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example">
|
|
|
<title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs</title>
|
|
<title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple montre comment posséder un enregistrement de la table d'origine <code>Bugs</code>, et
|
|
|
|
|
- comment en récupérer les enregistrements de <code>Products</code>, qui représentent les produits qui font
|
|
|
|
|
- référence à ce bug.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple montre comment posséder un enregistrement de la table d'origine
|
|
|
|
|
+ <code>Bugs</code>, et comment en récupérer les enregistrements de
|
|
|
|
|
+ <code>Products</code>, qui représentent les produits qui font référence à ce
|
|
|
|
|
+ bug.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -419,27 +561,45 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Les troisième et quatrième paramètres, <code>$rule1</code> et <code>$rule2</code>, sont optionnels. Ce
|
|
|
|
|
- sont des chaînes de caractères qui désignent les rôles à utiliser dans le tableau <code>$_referenceMap</code> de
|
|
|
|
|
- la table d'intersection.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para><code>$rule1</code> nomme le rôle dans la relation entre la table d'origine et la table d'intersection.
|
|
|
|
|
- Dans notre exemple, il s'agit donc de la relation de <code>Bugs</code> à <code>BugsProducts</code>.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para><code>$rule2</code>nomme le rôle dans la relation entre la table d'origine et la table d'intersection.
|
|
|
|
|
- Dans notre exemple, il s'agit donc de la relation de <code>BugsProducts</code> à <code>Products</code>.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Si vous ne spécifiez pas de rôles, alors le premier rôle trouvé pour la table, dans le tableau
|
|
|
|
|
- <code>$_referenceMap</code>, sera utilisé. Dans la grande majorité des cas, il n'y a qu'un rôle.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Dans l'exemple ci-dessus, les rôles ne sont pas spécifiés. Ainsi <code>$rule1</code> prend la valeur
|
|
|
|
|
- <code>"Reporter"</code> et <code>$rule2</code> prend la valeur <code>"Product"</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les troisième et quatrième paramètres, <code>$rule1</code> et <code>$rule2</code>,
|
|
|
|
|
+ sont optionnels. Ce sont des chaînes de caractères qui désignent les rôles à utiliser
|
|
|
|
|
+ dans le tableau <code>$_referenceMap</code> de la table d'intersection.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$rule1</code> nomme le rôle dans la relation entre la table d'origine et la
|
|
|
|
|
+ table d'intersection. Dans notre exemple, il s'agit donc de la relation de
|
|
|
|
|
+ <code>Bugs</code> à <code>BugsProducts</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$rule2</code>nomme le rôle dans la relation entre la table d'origine et la
|
|
|
|
|
+ table d'intersection. Dans notre exemple, il s'agit donc de la relation de
|
|
|
|
|
+ <code>BugsProducts</code> à <code>Products</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si vous ne spécifiez pas de rôles, alors le premier rôle trouvé pour la table,
|
|
|
|
|
+ dans le tableau <code>$_referenceMap</code>, sera utilisé. Dans la grande majorité des
|
|
|
|
|
+ cas, il n'y a qu'un rôle.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans l'exemple ci-dessus, les rôles ne sont pas spécifiés. Ainsi
|
|
|
|
|
+ <code>$rule1</code> prend la valeur <code>"Reporter"</code> et <code>$rule2</code> prend
|
|
|
|
|
+ la valeur <code>"Product"</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example-by">
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example-by">
|
|
|
- <title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs avec un rôle spécifique</title>
|
|
|
|
|
|
|
+ <title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs avec un
|
|
|
|
|
+ rôle spécifique</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple montre comment à partir d'un enregistrement de <code>Bugs</code>, récupérer les
|
|
|
|
|
- enregistrements de <code>Products</code>, représentant les produits comportant ce bug.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple montre comment à partir d'un enregistrement de <code>Bugs</code>,
|
|
|
|
|
+ récupérer les enregistrements de <code>Products</code>, représentant les produits
|
|
|
|
|
+ comportant ce bug.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -452,45 +612,63 @@ $productsRowset = $bug1234->findManyToManyRowset('Products',
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>Vous pouvez récupérer l'enregistrement de destination d'une autre manière. En utilisant les "méthodes
|
|
|
|
|
- magiques". En effet, <classname>Zend_Db_Table_Row_Abstract</classname> va utiliser la méthode
|
|
|
|
|
- <code>findManyToManyRowset('<TableClass>', '<IntersectionTableClass>', '<Rule1>',
|
|
|
|
|
- '<Rule2>')</code> si vous appelez sur l'enregistrement une méthode correspondante à un de ces motifs
|
|
|
|
|
- :</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Vous pouvez récupérer l'enregistrement de destination d'une autre manière. En
|
|
|
|
|
+ utilisant les "méthodes magiques". En effet,
|
|
|
|
|
+ <classname>Zend_Db_Table_Row_Abstract</classname> va utiliser la méthode
|
|
|
|
|
+ <code>findManyToManyRowset('<TableClass>', '<IntersectionTableClass>',
|
|
|
|
|
+ '<Rule1>', '<Rule2>')</code> si vous appelez sur l'enregistrement une
|
|
|
|
|
+ méthode correspondante à un de ces motifs :
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<itemizedlist>
|
|
<itemizedlist>
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><code>$row->find<TableClass>Via<IntersectionTableClass>([Zend_Db_Table_Select
|
|
|
|
|
- $select])</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>([Zend_Db_Table_Select
|
|
|
|
|
+ $select])</code>
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>([Zend_Db_Table_Select
|
|
|
|
|
- $select])</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>([Zend_Db_Table_Select
|
|
|
|
|
+ $select])</code>
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
|
|
|
|
|
<listitem>
|
|
<listitem>
|
|
|
- <para><code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>([Zend_Db_Table_Select
|
|
|
|
|
- $select])</code></para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <code>$row->find<TableClass>Via<IntersectionTableClass>By<Rule1>And<Rule2>([Zend_Db_Table_Select
|
|
|
|
|
+ $select])</code>
|
|
|
|
|
+ </para>
|
|
|
</listitem>
|
|
</listitem>
|
|
|
</itemizedlist>
|
|
</itemizedlist>
|
|
|
|
|
|
|
|
- <para>Dans les motifs ci dessus, <code><TableClass></code> et <code><IntersectionTableClass></code>
|
|
|
|
|
- sont des chaînes de caractères correspondantes aux noms des classes des tables de destination et d'intersection
|
|
|
|
|
- (respectivement). <code><Rule1></code> et <code><Rule2></code> sont respectivement des chaînes
|
|
|
|
|
- désignant les rôles dans la table d'intersection pour la table de référence, et de destination.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans les motifs ci dessus, <code><TableClass></code> et
|
|
|
|
|
+ <code><IntersectionTableClass></code> sont des chaînes de caractères
|
|
|
|
|
+ correspondantes aux noms des classes des tables de destination et d'intersection
|
|
|
|
|
+ (respectivement). <code><Rule1></code> et <code><Rule2></code> sont
|
|
|
|
|
+ respectivement des chaînes désignant les rôles dans la table d'intersection pour la
|
|
|
|
|
+ table de référence, et de destination.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<note>
|
|
<note>
|
|
|
- <para>Les noms de la table et des rôles doivent être orthographiés de manière exacte, tel qu'ils le sont
|
|
|
|
|
- lors de leurs définitions respectives.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les noms de la table et des rôles doivent être orthographiés de manière
|
|
|
|
|
+ exacte, tel qu'ils le sont lors de leurs définitions respectives.
|
|
|
|
|
+ </para>
|
|
|
</note>
|
|
</note>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example-magic">
|
|
<example id="zend.db.table.relationships.fetching.many-to-many.example-magic">
|
|
|
- <title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs avec les méthodes
|
|
|
|
|
- magiques</title>
|
|
|
|
|
|
|
+ <title>Récupérer des enregistrements dans une relation plusieurs-à-plusieurs avec
|
|
|
|
|
+ les méthodes magiques</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple illustre la récupération d'enregistrements dans une table de destination, bugs, depuis un
|
|
|
|
|
- produit, en passant par une table d'intersection, le tout, via des méthodes magiques.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple illustre la récupération d'enregistrements dans une table de
|
|
|
|
|
+ destination, bugs, depuis un produit, en passant par une table d'intersection, le
|
|
|
|
|
+ tout, via des méthodes magiques.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$bugsTable = new Bugs();
|
|
$bugsTable = new Bugs();
|
|
@@ -512,32 +690,50 @@ $products = $bug1234->findProductsViaBugsProductsByBug();
|
|
|
<note>
|
|
<note>
|
|
|
<title>Déclarer l'intégrité référentielle</title>
|
|
<title>Déclarer l'intégrité référentielle</title>
|
|
|
|
|
|
|
|
- <para>Déclarer les opérations de cascades dûes à l'intégrité référentielle dans <classname>Zend_Db_Table</classname>
|
|
|
|
|
- directement, ne doit se faire <emphasis>seulement</emphasis> si votre SGBD ne supporte pas
|
|
|
|
|
- nativement ce genre d'opérations.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>C'est le cas par exemple de MySQL utilisant le stockage de tables MyISAM, ou encore SQLite. Ces
|
|
|
|
|
- solutions là ne supportent pas l'intégrité référentielle. Il peut alors être intéressant d'utiliser
|
|
|
|
|
- <classname>Zend_Db_Table</classname> pour émuler un tel comportement</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Si votre SGBD en revanche supporte les clauses <code>ON DELETE</code> et <code>ON UPDATE</code>, alors
|
|
|
|
|
- vous devriez les déclarer directement dans le SGBD plutôt que de vous fier à l'émulation proposée par
|
|
|
|
|
- <classname>Zend_Db_Table</classname>. Déclarer son intégrité référentielle dans son SGBD directement est tout à fait
|
|
|
|
|
- recommandé pour les performances, l'intégrité (l'atomicité des opérations), et la logique de base de
|
|
|
|
|
- données.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Il est très important de ne pas déclarer ses règles d'intégrité référentielle à la fois dans son SGBD
|
|
|
|
|
- et dans les classes <classname>Zend_Db_Table</classname>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Déclarer les opérations de cascades dûes à l'intégrité référentielle dans
|
|
|
|
|
+ <classname>Zend_Db_Table</classname> directement, ne doit se faire
|
|
|
|
|
+ <emphasis>seulement</emphasis> si votre SGBD ne supporte pas nativement ce genre
|
|
|
|
|
+ d'opérations.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ C'est le cas par exemple de MySQL utilisant le stockage de tables MyISAM, ou
|
|
|
|
|
+ encore SQLite. Ces solutions là ne supportent pas l'intégrité référentielle. Il peut
|
|
|
|
|
+ alors être intéressant d'utiliser <classname>Zend_Db_Table</classname> pour émuler
|
|
|
|
|
+ un tel comportement
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Si votre SGBD en revanche supporte les clauses <code>ON DELETE</code> et
|
|
|
|
|
+ <code>ON UPDATE</code>, alors vous devriez les déclarer directement dans le SGBD
|
|
|
|
|
+ plutôt que de vous fier à l'émulation proposée par
|
|
|
|
|
+ <classname>Zend_Db_Table</classname>. Déclarer son intégrité référentielle dans son
|
|
|
|
|
+ SGBD directement est tout à fait recommandé pour les performances, l'intégrité
|
|
|
|
|
+ (l'atomicité des opérations), et la logique de base de données.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Il est très important de ne pas déclarer ses règles d'intégrité référentielle
|
|
|
|
|
+ à la fois dans son SGBD et dans les classes
|
|
|
|
|
+ <classname>Zend_Db_Table</classname>.
|
|
|
|
|
+ </para>
|
|
|
</note>
|
|
</note>
|
|
|
|
|
|
|
|
- <para>Vous pouvez déclarer des opérations de cascade sur un <code>UPDATE</code> ou un <code>DELETE</code>, à
|
|
|
|
|
- appliquer sur les enregistrements dépendants à la table en cours.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Vous pouvez déclarer des opérations de cascade sur un <code>UPDATE</code> ou un
|
|
|
|
|
+ <code>DELETE</code>, à appliquer sur les enregistrements dépendants à la table en
|
|
|
|
|
+ cours.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.cascading.example-delete">
|
|
<example id="zend.db.table.relationships.cascading.example-delete">
|
|
|
<title>Exemple de DELETE cascade</title>
|
|
<title>Exemple de DELETE cascade</title>
|
|
|
|
|
|
|
|
- <para>Cet exemple montre l'effacement d'un enregistrement de <code>Products</code>, qui va propager
|
|
|
|
|
- l'effacement des enregistrements dépendants dans la table <code>Bugs</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cet exemple montre l'effacement d'un enregistrement de <code>Products</code>,
|
|
|
|
|
+ qui va propager l'effacement des enregistrements dépendants dans la table
|
|
|
|
|
+ <code>Bugs</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
$productsTable = new Products();
|
|
$productsTable = new Products();
|
|
@@ -550,30 +746,44 @@ $product1234->delete();
|
|
|
]]></programlisting>
|
|
]]></programlisting>
|
|
|
</example>
|
|
</example>
|
|
|
|
|
|
|
|
- <para>De la même manière, si vous utilisez un <code>UPDATE</code> pour changer la valeur de la clé primaire
|
|
|
|
|
- d'une table parente, vous pourriez nécessiter que les clés étrangères des tables dépendantes soient mises à
|
|
|
|
|
- jour.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>En général s'il s'agit d'une séquence, il n'est pas nécessaire de mettre à jour les enregistrements
|
|
|
|
|
- dépendants. En revanche concernant les clé dites <emphasis>naturelles </emphasis>, il peut s'avérer nécessaire
|
|
|
|
|
- de propager un changement de valeur.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Afin de déclarer une relation de cascades dans <classname>Zend_Db_Table</classname>, éditer les rôles dans
|
|
|
|
|
- <code>$_referenceMap</code>. Ajoutez les clés <code>'onDelete'</code> et <code>'onUpdate'</code> et donnez leur
|
|
|
|
|
- la valeur 'cascade' (ou la constante <code>self::CASCADE</code>). Avant qu'un enregistrement ne soit modifié(sa
|
|
|
|
|
- clé primaire) / supprimé, tous les enregistrements dans les tables dépendantes seront modifiés /
|
|
|
|
|
- supprimés.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ De la même manière, si vous utilisez un <code>UPDATE</code> pour changer la valeur
|
|
|
|
|
+ de la clé primaire d'une table parente, vous pourriez nécessiter que les clés étrangères
|
|
|
|
|
+ des tables dépendantes soient mises à jour.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ En général s'il s'agit d'une séquence, il n'est pas nécessaire de mettre à jour
|
|
|
|
|
+ les enregistrements dépendants. En revanche concernant les clé dites
|
|
|
|
|
+ <emphasis>naturelles </emphasis>, il peut s'avérer nécessaire de propager un changement
|
|
|
|
|
+ de valeur.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Afin de déclarer une relation de cascades dans
|
|
|
|
|
+ <classname>Zend_Db_Table</classname>, éditer les rôles dans <code>$_referenceMap</code>.
|
|
|
|
|
+ Ajoutez les clés <code>'onDelete'</code> et <code>'onUpdate'</code> et donnez leur la
|
|
|
|
|
+ valeur 'cascade' (ou la constante <code>self::CASCADE</code>). Avant qu'un
|
|
|
|
|
+ enregistrement ne soit modifié(sa clé primaire) / supprimé, tous les enregistrements
|
|
|
|
|
+ dans les tables dépendantes seront modifiés / supprimés.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<example id="zend.db.table.relationships.cascading.example-declaration">
|
|
<example id="zend.db.table.relationships.cascading.example-declaration">
|
|
|
<title>Exemple de déclaration des opérations de cascade</title>
|
|
<title>Exemple de déclaration des opérations de cascade</title>
|
|
|
|
|
|
|
|
- <para>Dans l'exemple ci-après, les enregistrements de <code>Bugs</code> sont automatiquement supprimés si
|
|
|
|
|
- l'enregistrement dans la table <code>Products</code> auquel ils font référence est supprimé. L'élément
|
|
|
|
|
- <code>"onDelete"</code> de la <code>$_referenceMap</code> est mis à <code>self::CASCADE</code>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Dans l'exemple ci-après, les enregistrements de <code>Bugs</code> sont
|
|
|
|
|
+ automatiquement supprimés si l'enregistrement dans la table <code>Products</code>
|
|
|
|
|
+ auquel ils font référence est supprimé. L'élément <code>"onDelete"</code> de la
|
|
|
|
|
+ <code>$_referenceMap</code> est mis à <code>self::CASCADE</code>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
- <para>Pas de mise à jour en cascade en revanche pour cette table, si la clé primaire de la table parente est
|
|
|
|
|
- changée. En effet, l'élément <code>"onUpdate"</code> est mis à <code>self::RESTRICT</code>. Vous auriez
|
|
|
|
|
- aussi pu tout simplement ne pas spécifier <code>"onUpdate"</code> .</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Pas de mise à jour en cascade en revanche pour cette table, si la clé primaire
|
|
|
|
|
+ de la table parente est changée. En effet, l'élément <code>"onUpdate"</code> est mis
|
|
|
|
|
+ à <code>self::RESTRICT</code>. Vous auriez aussi pu tout simplement ne pas spécifier
|
|
|
|
|
+ <code>"onUpdate"</code> .
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<programlisting role="php"><![CDATA[
|
|
<programlisting role="php"><![CDATA[
|
|
|
class BugsProducts extends Zend_Db_Table_Abstract
|
|
class BugsProducts extends Zend_Db_Table_Abstract
|
|
@@ -596,46 +806,69 @@ class BugsProducts extends Zend_Db_Table_Abstract
|
|
|
<sect3 id="zend.db.table.relationships.cascading.notes">
|
|
<sect3 id="zend.db.table.relationships.cascading.notes">
|
|
|
<title>Notes concernant les opérations de cascade</title>
|
|
<title>Notes concernant les opérations de cascade</title>
|
|
|
|
|
|
|
|
- <para><emphasis>Les opérations de cascades déclenchées par Zend_Db_Table ne sont pas
|
|
|
|
|
- atomiques.</emphasis></para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Ceci signifie que si votre SGBD possède un moyen de gérer les cascades, comme l'intégrité
|
|
|
|
|
- référentielle (et les clés étrangères), alors vous ne devriez pas utiliser les cascades INSERT via
|
|
|
|
|
- <classname>Zend_Db_Table</classname>, car elles vont entrer en conflit avec le système d'intégrité référentielle du
|
|
|
|
|
- SGBD qui lui, est atomique.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Le problème est plus mitigé concernant <code>DELETE</code>. Vous pouvez détruire de manière non
|
|
|
|
|
- atomique un enregistrement dépendant, avant de détruire son parent.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Cependant, les deux opérations <code>UPDATE</code> et <code>DELETE</code> utilisées de manière non
|
|
|
|
|
- atomique(que), c'est à dire avec le mécanisme de <classname>Zend_Db_Table</classname>, peuvent laisser la base de
|
|
|
|
|
- données dans un état non désiré, ou état intermédiaire. Supposez que vous supprimiez tous les
|
|
|
|
|
- enregistrements dépendants, pour finir par leur parent unique. A un moment donnée, la base de donnée sera
|
|
|
|
|
- dans un état tel que le parent sera sans enfants, mais toujours bel et bien présent. Si un autre client se
|
|
|
|
|
- connecte exactement à ce moment là, il va pouvoir requêter éventuellement le parent, en croyant que celui-ci
|
|
|
|
|
- n'a plus d'enfant, ce qui normalement n'est pas le cas. Il est alors totalement impossible pour ce client là
|
|
|
|
|
- de se rendre compte qu'il a effectuer une lecture au beau milieu d'une plus vaste opération
|
|
|
|
|
- d'effacement.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Les problèmes de changements non-atomique peuvent être anéantis en utilisant les transactions
|
|
|
|
|
- isolantes, c'est d'ailleurs un de leur rôle clé. Cependant certains SGBDs ne supportent pas encore les
|
|
|
|
|
- transactions, et autorisent leurs clients à lire des changements incomplets pas validés en totalité.</para>
|
|
|
|
|
-
|
|
|
|
|
- <para><emphasis>Les opérations de cascades de Zend_Db_Table ne sont utilisées que par
|
|
|
|
|
- Zend_Db_Table.</emphasis></para>
|
|
|
|
|
-
|
|
|
|
|
- <para>Les cascades pour <code>DELETE</code> et <code>UPDATE</code> définies dans vos classes
|
|
|
|
|
- <classname>Zend_Db_Table</classname> ne sont utilisées que lors du recours aux méthodes <code>save()</code> ou
|
|
|
|
|
- <code>delete()</code> sur les enregistrements <code>Row</code>. Si vous utilisez une autre interface pour
|
|
|
|
|
- vos <code>UPDATE</code> ou <code>DELETE</code>, comme par exemple un outil de requêtes, ou une autre
|
|
|
|
|
- application, les opérations de cascades ne sont bien sûr pas appliquées. C'est même le cas si vous utilisez
|
|
|
|
|
- les méthodes <code>update()</code> et <code>delete()</code> dans la classe
|
|
|
|
|
- <classname>Zend_Db_Adapter</classname>.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>Les opérations de cascades déclenchées par Zend_Db_Table ne sont pas
|
|
|
|
|
+ atomiques.</emphasis>
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Ceci signifie que si votre SGBD possède un moyen de gérer les cascades, comme
|
|
|
|
|
+ l'intégrité référentielle (et les clés étrangères), alors vous ne devriez pas
|
|
|
|
|
+ utiliser les cascades INSERT via <classname>Zend_Db_Table</classname>, car elles
|
|
|
|
|
+ vont entrer en conflit avec le système d'intégrité référentielle du SGBD qui lui,
|
|
|
|
|
+ est atomique.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le problème est plus mitigé concernant <code>DELETE</code>. Vous pouvez
|
|
|
|
|
+ détruire de manière non atomique un enregistrement dépendant, avant de détruire son
|
|
|
|
|
+ parent.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Cependant, les deux opérations <code>UPDATE</code> et <code>DELETE</code>
|
|
|
|
|
+ utilisées de manière non atomique(que), c'est à dire avec le mécanisme de
|
|
|
|
|
+ <classname>Zend_Db_Table</classname>, peuvent laisser la base de données dans un
|
|
|
|
|
+ état non désiré, ou état intermédiaire. Supposez que vous supprimiez tous les
|
|
|
|
|
+ enregistrements dépendants, pour finir par leur parent unique. A un moment donnée,
|
|
|
|
|
+ la base de donnée sera dans un état tel que le parent sera sans enfants, mais
|
|
|
|
|
+ toujours bel et bien présent. Si un autre client se connecte exactement à ce moment
|
|
|
|
|
+ là, il va pouvoir requêter éventuellement le parent, en croyant que celui-ci n'a
|
|
|
|
|
+ plus d'enfant, ce qui normalement n'est pas le cas. Il est alors totalement
|
|
|
|
|
+ impossible pour ce client là de se rendre compte qu'il a effectuer une lecture au
|
|
|
|
|
+ beau milieu d'une plus vaste opération d'effacement.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les problèmes de changements non-atomique peuvent être anéantis en utilisant
|
|
|
|
|
+ les transactions isolantes, c'est d'ailleurs un de leur rôle clé. Cependant certains
|
|
|
|
|
+ SGBDs ne supportent pas encore les transactions, et autorisent leurs clients à lire
|
|
|
|
|
+ des changements incomplets pas validés en totalité.
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ <emphasis>Les opérations de cascades de Zend_Db_Table ne sont utilisées que
|
|
|
|
|
+ par Zend_Db_Table.</emphasis>
|
|
|
|
|
+ </para>
|
|
|
|
|
+
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Les cascades pour <code>DELETE</code> et <code>UPDATE</code> définies dans vos
|
|
|
|
|
+ classes <classname>Zend_Db_Table</classname> ne sont utilisées que lors du recours
|
|
|
|
|
+ aux méthodes <code>save()</code> ou <code>delete()</code> sur les enregistrements
|
|
|
|
|
+ <code>Row</code>. Si vous utilisez une autre interface pour vos <code>UPDATE</code>
|
|
|
|
|
+ ou <code>DELETE</code>, comme par exemple un outil de requêtes, ou une autre
|
|
|
|
|
+ application, les opérations de cascades ne sont bien sûr pas appliquées. C'est même
|
|
|
|
|
+ le cas si vous utilisez les méthodes <code>update()</code> et <code>delete()</code>
|
|
|
|
|
+ dans la classe <classname>Zend_Db_Adapter</classname>.
|
|
|
|
|
+ </para>
|
|
|
|
|
|
|
|
<para><emphasis>Pas d'<code>INSERT</code> en cascade</emphasis></para>
|
|
<para><emphasis>Pas d'<code>INSERT</code> en cascade</emphasis></para>
|
|
|
|
|
|
|
|
- <para>Le support pour les cascades d'<code>INSERT</code> n'est pas assuré. Vous devez explicitement insérer
|
|
|
|
|
- les enregistrements dépendants à un enregistrement parent.</para>
|
|
|
|
|
|
|
+ <para>
|
|
|
|
|
+ Le support pour les cascades d'<code>INSERT</code> n'est pas assuré. Vous
|
|
|
|
|
+ devez explicitement insérer les enregistrements dépendants à un enregistrement
|
|
|
|
|
+ parent.
|
|
|
|
|
+ </para>
|
|
|
</sect3>
|
|
</sect3>
|
|
|
</sect2>
|
|
</sect2>
|
|
|
</sect1>
|
|
</sect1>
|