Bonjour,
travaillant avec la version 1.2.3 de Doctrine (et Symfony 1.4.8), nous avons été confronté à une problématique qui revient souvent dans les forums. Je n'ai pas forcément cherché longtemps, mais il n'y a, à ma connaissance, pas encore de moyen de contournement propre.
La problématique est la suivante : Comment faire pour réaliser des jointures entre des tables qui sont dans des bases de données différentes (à noter ici, que nous travaillons avec MySQL/InnoDB).
j'ai donc un peu travaillé sur le sujet, et je suis arrivé à quelque chose qui me convient et que j'ai soumis au projet Doctrine.
Je tiens cependant à vous faire part du résultat pour que vous puissiez m'apporter vos critiques.
le premier point est d'ajouter une constante à la classe Doctrine_Core. Voir le fichier une fois modifié mis en pièce jointe.
const ATTR_DATABASE_NAME = 0x1DB;
Cette nouvelle constante permet d'ajouter, dans le fichier databases.yml, un attribut optionnel database_name, qui permet d'indiquer le nom de la base de données attachée au DSN doctrine.
exemple :
1 2 3 4 5 6 7 8 9 10
| gesdoc:
class: sfDoctrineDatabase
param:
dsn: mysql:host=127.0.0.1;dbname=gesdoc
username: root
password:
attributes:
database_name: gesdoc
default_table_collate: utf8_general_ci
default_table_charset: utf8 |
de là, un certain nombre de modifications (très peu, en fait) ont été apportées dans la classe Doctrine_Query. Ces modifications démarrent aux lignes 1759, 1862, 1971 et 1983. Voir pour cela, le fichier en pièce jointe.
Ensuite, pour peu que les modèles aient été bien préparés, il sera possible de générer des requêtes Doctrine avec des jointures entre bases de données.
La préparation des modèles passe par la bonne écriture du schema.yml en y indiquant la connexion à utiliser pour chaque modèle.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| Document:
connection: gesdoc
tableName: document
columns:
...
relations:
Contrat:
local: contrat_id
foreign: id
type: one
...
Contrat:
connection: gescdc
tableName: contrat
columns:
... |
ce qui permet de générer pour l'exemple ci dessus un modèle Document (lié à la connexion "gesdoc"), référençant le modèle Contrat (lié à la connexion "gescdc") via une relation many2one.
les modèles auront ainsi le schéma suivant :
1 2 3 4
| Doctrine_Manager::getInstance()->bindComponent('Document', 'gesdoc');
abstract class BaseDocument extends sfDoctrineRecord{
...
} |
et
1 2 3 4 5
|
Doctrine_Manager::getInstance()->bindComponent('Contrat', 'gescdc');
abstract class BaseContrat extends sfDoctrineRecord{
...
} |
la requete suivante peut alors s'exécuter sans problème majeur :
1 2 3
| $x = DocumentTable::getInstance()->createQuery('d')
->leftJoin('d.Contrat c')
->execute(); |
Voila, je ne sais pas si certains d'entre vous ont déjà été confronté à ce problème, mais cette solution semble corriger cette limitation de Doctrine.
toute remarque/correction est évidemment la bienvenue, puisqu'il est possible que je sois passé à côté de quelque chose lors de mes tests de régression.
HTH.
Partager