Ce module est
EXPERIMENTAL. Cela signifie que le comportement de ces
fonctions, leurs noms et concrètement, TOUT ce qui est documenté ici peut
changer dans un futur proche, SANS PREAVIS! Soyez-en conscient, et utilisez
ce module à vos risques et périls.
Afin d'utiliser le Service d'Accès de Données Relationnel pour les Objets
de Service de Données, vous devrez comprendre certains concepts derrière
le SDO : le graphique de données, l'objet de données, le moyen de
déconnexion pour travailler, le changement du sommaire, les expressions
XPath et les propriétés, et ainsi de suite. Si vous n'êtes pas familier
avec ses idées, vous devriez regarder en premier à la section sur le SDO. De plus, le DAS
Relationnel utilise l'extension SDO pour s'isoler des communications
spécifiques aux bases de données. Afin d'utiliser le DAS Relationnel, vous
devrez être capable de créer et passer une connexion de base de données
PDO; pour cette raison, vous devrez aussi regarder la section sur le PDO.
Le travail de DAS Relationnel est de déplacer les données entre les
applications et une base de données relationnelle. Afin de faire cela, vous
devez dire quelle sorte de données vont être transférées entre les
entités de base de données
- tables, colonnes, clés primaires et clés étrangères -
et les éléments de modèle SDO
- types, propriétés, relations de retenue et ainsi de suite.
Vous spécifiez ces informations comme des méta-données lorsque vous
construisez le DAS Relationnel.
Vue d'ensemble des Opérations
La première étape est d'appeler le constructeur de DAS Relationnel, en
lui passant les méta-données qui définissent les relations entre la base de
données et le modèle SDO. Il y a des exemples plus bas.
L'étape suivante devrait être l'appel des méthodes
executeQuery()
ou
executePreparedQuery()
sur le DAS Relationnel, en leur passant soit une requête SQL littérale
pour le DAS pour préparer et exécuter ou une requête préparée avec des
paramètres fictifs et une liste des valeurs à être insérées. Vous pouvez
aussi avoir besoin de spécifier un peu de méta-données à propos de la
requête, ainsi le DAS Relationnel saura exactement quelles colonnes
seront retournées de la base de données et dans quel ordre. Vous devez
aussi passer une connexion de base de données PDO.
La valeur de retour de
executeQuery()
ou
executePreparedQuery()
est un graphique de données normalisé contenant toutes les données du
jeu de résultats. Pour une requête qui retourne les données obtenues Ã
partir de plusieurs tables, ce graphique contiendra plusieurs objets
de données, liés avec les relations SDO contenues. Il pourrait aussi
y avoir des données de références qui ne sont pas de contenues Ã
l'intérieur des données.
Une fois que la requête a été exécutée et le graphique de données
construit, il n'est pas nécessaire pour l'instance de DAS Relationnel ou
pour la connexion de base de données. Il n'y a pas de verrou gardé sur
la base de données. Le DAS Relationnel et la connexion de base de
données PDO peuvent être tous deux passés au ramasse miettes.
Il est probable que les données dans le graphique de données passent par
plusieurs modifications. Le graphique de données peut être sérialisé
dans une session PHP et ainsi peut avoir une vie au-delà d'une
interaction client-serveur. Les objets de données peuvent être créés et
ajoutés au graphique, les objets de données déjà dans le graphique
peuvent être supprimés et les objets de données dans le graphique
peuvent être modifiés.
Enfin, les changements effectués sur le graphique de données peuvent
être appliqués à la base de donnés en utilisant la méthode
applyChanges()
de DAS Relationnel. Pour cela, une autre instance de DAS Relationnel
doit être construite, en utilisant les mêmes méta-données, et une autre
connexion à la base de données obtenue. La connexion et le graphique de
données sont passés Ã
applyChanges().
À ce point, le DAS Relationnel examine les changements et génère les
requêtes SQL INSERT, UPDATE et DELETE nécessaires pour appliquer les
changements. Toutes les requêtes UPDATE et DELETE sont qualifiées avec
les valeurs originales des données, donc il se peut que les données
aillent changées dans la base de données en attendant que les données
soient détectées. En assumant qu'aucune collision de ce type ne s'est
produite, les changements seront envoyés à la base de données.
L'application peut alors continuer à travailler avec le graphique de
données, effectuer d'autres changements et les appliquer, ou peut le
jeter.
Il y a d'autres moyens de travailler avec les données dans la base de
données : il est possible de créer simplement les objets de données et les
écrire à la base de données sans effectuer d'appel préliminaire Ã
executeQuery(),
par exemple. Ce scénario et les autres sont explorés dans les
exemples de la section plus
bas.
Le DAS Relationnel requière que l'extension SDO soit installée.
L'extension SDO requière une version de PHP 5.1 et le DAS Relationnel
requière une version récente qui contient une mise à jour importante de
PDO. Les informations les plus à jours à propos des niveaux requis de
PHP devrait être trouvées dans le changelog pour ce paquetage sur PECL.
Au moment que nous écrivons cette documentation, le DAS Relationnel
requière le plus récent niveau de bêta de PHP 5.1, qui est PHP
5.1.0b3.
Le DAS Relationnel utilise le PDO pour accéder à une base de données
relationnelle et devrait fonctionner avec une variété différente de bases
de données. Au moment que nous écrivons cette documentation, cela a été
testé avec les configurations suivantes
MySQL 4.1.14, sur Windows.
Le DAS Relationnel opère correctement avec le pilote php_pdo_mysql qui
vient avec les programmes pré-configurés binaires de PHP 5.1.0b3.
MySQL 4.1.13, sur Linux.
Il est nécessaire d'avoir le plus récent pilote de PDO pour MySQL, qui
vient avec un PHP. 5.1.0b3. Il se peut qu'il soit nécessaire de
désinstaller les pilotes utilisés qui seraient venus de PECL en
utilisant
pear uninstall pdo_mysql
. Vous devrez configurer votre PHP avec l'option
--with-pdo-mysql.
DB2 8.2 Édition Personnelle, sur Windows.
Le DAS Relationnel opère correctement avec le pilote php_pdo_odbc qui
vient avec les programmes pré-configurés binaires de PHP 5.1.0b3.
DB2 8.2 Édition Personnelle de Développeur, sur Linux.
L'édition e Développeur est requise puisqu'elle contient les fichiers
d'inclusion requis lorsque PHP est configuré et bâti. Vous devrez
configurer PHP avec l'option
--with-pdo-odbc=ibm-db2.
Le DAS Relationnel applique les changements à la base de données Ã
l'intérieur de transactions délimitées par l'utilisateur : cela appel la
méthode
PDO::beginTransaction()
avant de commencer à appliquer les changements et
PDO::commit()
ou
PDO::rollback()
lorsque c'est complété.
Peu importe la base de données qui est choisie, la base de données et le
pilote PDO pour cette base de données doivent supporter ces appels.
Il y a les limitations suivantes dans la version courante de DAS
Relationnel :
Aucun support pour les données NULL. Il n'y a pas de support pour les
types de SQL NULL. Cela n'est pas légal d'assigner une donnée PHP
NULL Ã une propriété d'objet de données et le DAS Relationnel
n'écriera pas en tant que NULL Ã la base de données. Si des données
NULL sont trouvées dans la base de données dans une requête, la
propriété restera non fixée.
Seulement deux types de relation SDO. Les méta-données décrient plus bas
permettent le DAS Relationnel de modéliser seulement deux types de
relation SDO : relations contenues de valeurs multiples et les
références contenues de valeurs simples. Dans SDO, si une
propriété décrit une relation simple ou de valeurs multiples, et si
c'est contenu ou non contenu, elle est indépendante. La plage complète
des possibilités que SDO autorise ne peut être défini au complet. Il
peut y avoir des relations qui peuvent être utiles pour modéliser mais
que l'implémentation courante ne peut gérer.
Un exemple est de relation de simples valeurs contenues.
Aucun support pour la plage complète des types de données SDO. Le DAS
Relationnel définit des propriétés primitives dans le modèle SDO en
tant qu'un type de chaîne de caractères. SDO définit un ensemble de types plus
riche contenant des types entier, valeur à virgule flottante, booléen
et des données et de temps. Une chaîne de caractères est adéquate pour les
buts de DAS Relationnel puisque la combinaison de PHP, PDO et les
bases de données assurera que les valeurs passées en tant que chaînes
de caractères seront converties au bon type avant d'être envoyées à la
base de données. Cela affecte certains scénarios dans lesquels DAS
Relationnel doit travailler avec un graphique de données qui est venu
ou ira à un différent DAS.
Seulement une clé étrangère par table.
Les méta-données fournissent seulement le moyen de spécifier une clé
étrangère par table. Cette clé étrangère peut établir une
correspondance à un ou deux types de relations SDO supportés.
Évidemment, il y a des scénarios qui ne peuvent être décrits sous cette
limitation - il n'est pas possible d'avoir deux références non
contenues d'une table à une autre par exemple.
Cette section illustre comment le DAS Relationnel peut être utilisé pour
créer, récupérer, mettre â jour et supprimer des données dans une base de
données relationnelle. Plusieurs de ces exemples sont illustrés avec trois
tables dans une base de données qui contient "compagnies", "departements"
à l'intérieur de ces compagnies et "employes" qui travaillent dans ces
départements. Cet exemple est utilisé dans plusieurs places dans la
littérature SDO. Voyez la section des exemples de
spécification d'Objets de Service de
Données
ou la section d'exemples
de la documentation de l'extension SDO.
Le DAS Relationnel est construit avec les méta-données qui définissent la
base de données relationnelle et comment il devrait être en relation avec
le SDO. La longue section qui suit décrit ces méta-données et comment
construire le DAS Relationnel. Ces exemples qui suivent assument tous que
ces méta-données sont incluses dans un fichier PHP.
Les exemples ci-dessous et les autres peuvent être trouvés dans le dossier
Scenarios
dans le paquetage DAS Relationnel.
Le DAS Relationnel émet des exceptions dans le cas qu'il trouve des
erreurs dans les méta-données ou des erreurs lors de l'exécution des
requêtes SQL Ã la base de données. Pour rendre les exemples plus concis,
ils n'incluent pas les blocs try/catch autour des appels de DAS
Relationnel.
Ces exemples diffèrent tous de l'utilisation prévue de SDO dans deux
égards importants.
Premièrement, ils montrent toutes les interactions avec la base de données
complétés dans un script. Ces scénarios ne sont pas réalistes mais sont
choisis dans le but d'illustrer simplement l'utilisation de DAS
Relationnel. Il est prévu que les interactions avec la base de données
soient séparés dans le temps et le graphique de données sérialisés et
désérialisé dans une session PHP une ou plusieurs fois tant que
l'application interagit avec l'utilisateur final.
Deuxièmement, toutes les requêtes exécutées sur la base de données sont
figées dans le code sans aucune substitution de variable. Dans ce cas, il
est plus sage d'utiliser le simple appel de
executeQuery()
et c'est ce que montrent les exemples.
En pratique, il est peu probable que la requête SQL soit connue
entièrement avant son exécution. Afin d'autoriser la substitution sans
danger des variables dans les requêtes SQL, sans prendre le risque
d'effectuer des injections SQL avec des effets inconnus, il est plus
sécuritaire d'utiliser
executePreparedQuery()
qui prend une requête SQL préparée contenant des paramètres fictifs et une
liste des valeurs à être substituées.
La première longue section décrit en détail comment les méta-données
décrivant la base de données et le modèle SDO requis est fourni à DAS
Relationnel.
Lorsque le constructeur de DAS Relationnel est appelé, il doit recevoir
plusieurs informations. La majeure partie des informations, passée en
tant qu'un tableau associatif dans le premier argument du constructeur,
dit à DAS Relationnel ce qu'il doit savoir à propos de la base de données
relationnelle. Il décrit les noms des tables, des colonnes, des clés
primaires et des clés secondaires. On devrait comprendre assez facilement
ce qui est requis et une fois écrit, il peut être placé dans un fichier
PHP et inclut lorsque nécessaire. Le reste des informations, passé dans
un deuxième et troisième arguments du constructeur, dit au DAS
Relationnel ce qu'il doit savoir à propos des relations entre les objets
et la forme du graphique de données; il détermine finalement comment les
données de la base de données seront normalisées dans le graphique.
Le premier argument du constructeur décrit la base de données
relationnelle cible.
Chaque table est décrite par un tableau associatif avec jusqu'Ã quatre
clés.
Clé
Valeur
name
Le nom de la table.
columns
Un tableau listant les noms des colonnes, dans n'importe quel
ordre.
PK
Le nom de la colonne contenant la clé primaire.
FK
Un tableau avec deux entrées, 'from' et 'to' (provenance et
destination), qui définissent une colonne contenant la clé étrangère
et une table dans lequel la clé étrangère pointe. S'il n'y a pas de
clé étrangère dans la table, alors l'entrée 'FK' est optionnelle.
Seulement une clé étrangère peut être spécifiée. Seulement une clé
étrangère pointant à une clé primaire d'une table peut être
spécifiée.
Les méta-données correspondent à une base de données relationnelle qui
peut avoir été définie comme étant MySQL :
create table compagnie (
id integer auto_increment,
nom char(20),
employe_du_mois integer,
primary key(id)
);
create table department (
id integer auto_increment,
nom char(20),
emplacement char(10),
nombre integer(3),
co_id integer,
primary key(id)
);
create table employe (
id integer auto_increment,
nom char(20),
SN char(4),
gestionnaire tinyint(1),
dept_id integer,
primary key(id)
);
ou comme DB2 :
create table compagnie ( \
id integer not null generated by default as identity, \
nom varchar(20), \
employe_du_mois integer, \
primary key(id) )
create table department ( \
id integer not null generated by default as identity, \
nom varchar(20), \
emplacement varchar(10), \
nombre integer, \
co_id integer, \
primary key(id) )
create table employe ( \
id integer not null generated by default as identity, \
nom varchar(20), \
SN char(4), \
gestionnaire smallint, \
dept_id integer, \
primary key(id) )
Notez que bien que dans cet exemple n'a pas de clé étrangère de
spécifiée à la base de données et que la base de données n'est pas
prévue à forcer l'intégrité référentielle, l'intention derrière la
colonne
co_id
de la table departement et la colonne
dept_id
de la table employe est qu'elles pourraient contenir la clé primaire de
leur compagnie les contenant ou l'enregistrement du département,
respectivement.
Alors ces deux colonnes actent comme des clés étrangères.
Il y a une troisième clé étrangère dans cet exemple, elle est de la
colonne
employe_du_mois
de la table compagnie qui est compris dans une ligne de la table
employe.
Notez la différence dans l'intention entre cette clé étrangère et les
deux autres. La colonne
employe_du_mois
représente une relation de valeurs simples : il peut y avoir seulement
un employé du moi pour une compagnie donnée.
Les colonnes
co_iddept_id
représentent des relations de valeurs multiples : une compagnie peut
contenir plusieurs département et un département peut contenir beaucoup
d'employés. Cette distinction deviendra évidente lorsque le reste des
méta-données sélectionne les relations entre la compagnie-département et le
département-employé comme étant une relation contenue.
Il y a un peu de règles simples qui doivent être suivies lorsque l'on
construit les méta-données de base de données :
Toutes les tables doivent avoir des clés primaires et les clés
primaires doivent être spécifiées dans les méta-données. Sans clés
primaires, il n'est pas possible de garder une trace des identités des
objets. Comme vous pouvez le voir avec les requête SQL qui créent les
tables, les clés primaires peuvent être générées automatiquement, ce
qui signifie, qu'elles sont générées et assignées par la base de
données lorsque l'enregistrement est inséré. Dans ce cas, la clé
primaire générée automatiquement est obtenue de la base de données et
insérées dans l'objet de données immédiatement après que la ligne
soit insérée dans la base de données.
Il n'est pas nécessaire de spécifier les méta-données de toutes les
colonnes qui existent dans la base de données, seulement celles qui
seront utilisées. Par exemple, si la table compagnie avait un autre
colonne que l'application ne souhaite pas accéder avec SDO, il n'est
pas nécessaire de la spécifiée dans les méta-données. En contrepartie,
cela ne devrait pas causer de problème de la spécifier : si elle est
spécifiée dans les méta-données mais jamais récupérée ou assignée par
l'application, alors la colonne inutilisée ne devrait rien affecter.
Dans les méta-données de base de données, notez que les définitions
des clés étrangères n'identifient pas la colonne de destination dans
la table qui est pointée, mais le nom de la table elle-même.
Strictement, le modèle relationnel permet la destination d'une clé
étrangère à être une clé non primaire. Seules les clés étrangères qui
pointent à une clé primaire sont utiles pour la construction du
modèle SDO, puisque les méta-données spécifient le nom de la table. Il
est entendu que la clé étrangère pointe vers la clé primaire d'une
table donnée.
Ayant donné ces règles et les requêtes SQL qui définissent les bases de
données, les méta-données de base de données devrait être faciles Ã
construire.
Le DAS Relationnel utilise les méta-données de base de données pour
former la plupart des modèles SDO. Pour chaque table dans les
méta-données de base de données, un type SDO est défini. Chaque colonne
qui peut représenter une valeur primitive (les colonnes qui ne sont pas
définies comme étant des clés étrangères) est ajoutée comme propriété
au type SDO.
Toutes les propriétés primitives sont données par un type de chaîne de caractères
dans le modèle SDO, sans se soucier de leur type SQL. Lors de la
ré-écriture des données dans la base de données, le DAS Relationnel
créera une requête SQL qui traitera les valeurs comme étant des chaînes
de caractères et la base de données les convertira dans le type
approprié.
Les clés étrangères sont interprétées de une des deux manières,
dépendamment des méta-données contenues dans le troisième argument du
constructeur qui définissent les relations de SDO contenues.
Une discussion de cela est donc reportée dans la section
relations SDO contenues
ci-dessous.
Le second argument du constructeur est l'application du type de racine.
La vraie racine de chaque graphique de données est un objet d'un type de
racine spécial et tous les objets de données des applications viennent
quelque part sous cela. De la plupart des types d'application dans le
modèle SDO, une doit être le type d'application immédiatement sous la
racine du graphique de données. S'il y a seulement une table dans les
méta-données de base de données, le type de racine de l'application peut
être impliqué et cet argument peut être omis.
Le troisième argument du constructeur définit comment les types dans le
modèle seront liés ensemble pour former un graphique. Cela identifie les
relations parent-enfant entre les types qui collectivement forment un
graphique. Les relations doivent être supportées par les clés étrangères
pour être trouvées dans les données, d'une manière rapide d'être décrit.
Les méta-données sont un tableau contenant un ou plusieurs tableaux
associatifs, chacun d'eux identifie un parent et un enfant. L'exemple
ci-dessous montre une relation parent-enfant de compagnie au département
et un autre du département aux employés. Chacune d'elles deviendra un
propriété définissant une relation de valeur multiples contenue dans un
modèle SDO.
Les clés étrangères dans les méta-données de base de données sont
interprétées comme des propriétés avec soit des relations de valeurs
multiples contenues ou des références de simples valeurs non contenues,
dépendamment si elles ont une relation SDO contenue correspondante
spécifiée dans les méta-données. Dans cet exemple ici, les clés
étrangères du département à la compagnie (la colonne
co_id
dans la table de departement)
et de l'employé au département (la colonne
dept_id
dans la table employe) sont interprétées comme supportant les relations
SDO contenues.
Chaque référence contenue mentionnée dans les méta-données de relations
contenue de SDO doit avoir une clé correspondante présente dans la base
de données et définie dans les méta-données de base de données. Les
valeurs des colonnes de la clé étrangère pour les relations contenues
n'apparaissent pas dans les objets de données; Ã la place, chacune
d'entre elles est représentée par une relation contenue du parent Ã
l'enfant. Alors la colonne co_id dans la ligne de
département de la base de données, par exemple, n'apparaît pas en tant
que propriété du type de département, mais apparaît à la place comme
une relation contenue appelée departname sur le
type de compagnie. Notez que la clé étrangère et la relation
parent-enfant semble avoir un sens opposé : la clé étrangère pointe du
département à la compagnie, mais la relation parent-enfant pointe de
la compagnie au département.
La troisième clé dans cet exemple, le
employe_du_mois
,
est gérée différemment.
Elle n'est pas mentionnée dans les méta-données de relations SDO
contenues. Ceci a pour conséquence d'être interprété de la seconde manière :
elle devient une référence de valeur simple non contenue sur l'objet
compagnie, sur lequel vous pouvez assigner des références au type
d'employé d'objets de données SDO. Elle apparaît comme une propriété du
type de compagnie. Le moyen pour lui assigner une valeur dans le
graphique de données est d'avoir un graphique qui contient un objet
employé avec les relations contenues et d'assigner l'objet à celui-ci.
Ceci est montré dans les exemples plus loin.
Les exemples suivants utilisent tous le DAS Relationnel pour travailler
avec un graphique de données contenant juste un objet de données
d'application, une seule compagnie et les données qui seront dans la
table compagnie. Ces exemples ne montre pas le pouvoir de SDO ou de DAS
Relationnel et bien sûr les mêmes résultats peuvent être atteints plus
économiquement à l'aide de requêtes SQL directes mais ces exemples sont
pour vous montrer comment fonctionne le DAS Relationnel.
Pour ce simple scénario, il serait possible de simplifier les méta-données
de base de données pour inclure juste la table de compagnie - si cela
était fait, le deuxième et troisième argument du constructeur et le
spécificateur de colonne utilisé dans l'exemple de requête deviendrait
optionnel.
Exemple 1. Création d'un objet de données
Le plus simple exemple est de créer un objet de données simple et de
l'écrire à la base de données. Dans cet exemple, un objet simple de
compagnie est créé, son nom est fixé Ã 'Acme' et le DAS Relationnel est
appelé pour écrire les changements à la base de données. Le nom de la
compagnie est fixé ici en utilisant la méthode de propriété de nom.
Voyez la section d'exemples sur
l'extension SDO pour d'autres moyens d'accéder au propriétés d'un
objet.
Les objets de données peuvent seulement être créés lorsque vous avez un
objet de données au démarrage. C'est pour cette raison que le premier
appel à DAS Relationnel ici est pour obtenir l'objet racine. C'est en
effet comment demander pour un graphique de données vide - l'objet de
racine spécial est la vrai racine de l'arbre. L'objet de données
compagnie est alors créé avec l'appel Ã
createDataObject()
sur l'objet racine. Ceci crée l'objet de données compagnie et l'insère
dans le graphique en insérant une propriété de valeurs multiples
contenue dans l'objet racine appelé 'compagnie'.
Lorsque DAS Relationnel est appelé pour effectuer les changements, une
simple requête d'insertion
'INSERT INTO compagnie (nom} VALUES ("Acme");'
sera construite et exécutée. La clé primaire générée automatiquement
sera fixée dans l'objet de données et le changement sera effacé, alors
il serait possible de continuer de travailler avec le même objet de
données, le modifier, et applique les nouveaux changements une deuxième
fois.
/************************************************************** * Construit le DAS avec les méta-données ***************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
/************************************************************** * Obtient l'objet racine et crée un objet compagnie dessous. * Effectue un petit changement à l'objet de données. ***************************************************************/ $root = $das -> createRootDataObject(); $acme = $root -> createDataObject('compagnie');
$acme->name = "Acme";
/************************************************************** * Récupère la connexion à la base de données et écrit l'objet à la base de données ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $das -> applyChanges($dbh, $root); ?>
Exemple 2. Récupération d'un objet de données
Dans cet exemple, un simple objet de données est récupéré de la base de
données - ou possiblement plus d'un s'il y avait plus d'une compagnie
qui était appelée 'Acme'. Pour chaque compagnie retournée, les
propriétés
nom
et
id
sont affichées.
Dans cet exemple, le troisième argument de
executeQuery(),
le spécificateur de colonne est requis puisqu'il y a d'autres tables
dans les méta-données avec le nom de colonne
nom
et
id.
S'il n'y avait pas d'ambiguïté possible, il aurait pu être omis.
/************************************************************** * Construit le DAS avec les méta-données ***************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
/************************************************************** * Récupère la connexion à la base de données ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
/************************************************************** * Effectue une requête pour obtenir un objet compagnie - possiblement * plusieurs s'ils existent ***************************************************************/ $root = $das->executeQuery($dbh, 'select nom, id from compagnie where nom="Acme"', array('compagnie.nom', 'compagnie.id') );
/************************************************************** * Affiche le nom et le id ***************************************************************/ foreach ($root['compagnie'] as $compagnie) { echo "La compagnie obtenue de la base de données a le nom = " . $compagnie['nom'] . " et un id " . $compagnie['id'] . "\n"; } ?>
Exemple 3. Mise à jour d'objet de données
Cet exemple combine les deux précédent, dans le sens que pour être mis
à jour, l'objet doit être premièrement récupéré. L'application renverse
le nom de compagnie (alors 'Acme' devient 'emcA') et alors les
changements sont écrits à la base de données de la même manière qu'ils
étaient lorsque l'objet avait été créé. Puisque la requête cherche pour
le nom, on peut chercher des deux manières le nom Ã
plusieurs reprises pour trouver la compagnie et renverser son nom
chaque fois.
Dans cet exemple, la même instance de DAS Relationnel est réutilisée
pour
applyChanges(),
avec le descripteur de base de données PDO. Ceci est tout à fait
correcte; il est aussi possible d'autoriser les instances précédentes
d'être ramassées par le ramasse-miettes et d'obtenir de nouvelles
instances. Aucune données d'état concernant le graphique n'est tenue
par le DAS Relationnel une fois qu'il a retourné un graphique de
données à l'application. Toutes les données nécessaires sont soit dans
le graphique ou peuvent être reconstruites à partir des méta-données.
/************************************************************** * Construit le DAS avec les méta-données ***************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
/************************************************************** * Récupère la connexion à la base de données ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
/************************************************************** * Effectue une requête pour obtenir un objet compagnie - possiblement * plusieurs s'ils existent ***************************************************************/ $root = $das->executeQuery($dbh, 'select nom, id from compagnie where nom="Acme" or nom="emcA"', array('compagnie.nom', 'compagnie.id') );
/************************************************************** * Modifie le nom de la première compagnie seulement ***************************************************************/ $compagnie = $root['compagnie'][0]; echo "Compagnie obtenue avec le nom " . $compagnie->nom . "\n"; $compagnie->nom = strrev($compagnie->nom);
/************************************************************** * Écriture du changement ***************************************************************/ $das->applyChanges($dbh,$root); ?>
Exemple 4. Suppression d'un objet de données
Toutes compagnies appelées 'Acme' ou son inverse 'emcA' sont récupérées.
Elles sont ensuite toutes supprimées du graphique avec unset.
Dans l'exemple, elles sont toutes supprimées en un seul coup en
supprimant la propriété contenue (la propriété définissant la relation
contenue). Il est aussi possible de les supprimer individuellement.
/************************************************************** * Construit le DAS avec les méta-données ***************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
/************************************************************** * Récupère la connexion à la base de données ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
/************************************************************** * Effectue une requête pour obtenir un objet compagnie - possiblement * plusieurs s'ils existent ***************************************************************/ $root = $das->executeQuery($dbh, 'select nom, id from compagnie where nom="Acme" or nom="emcA"', array('company.name', 'company.id') );
/************************************************************** * Supprime les compagnies trouvées du graphique de données ***************************************************************/ unset($root['compagnie']);
Les exemples suivants utilisent tous deux tables de la base de données
compagnie : les tables compagnie et departement. Ces exemples montrent
plus le fonctionnement de DAS Relationnel.
Dans cette série d'exemples, une compagnie et un département son créé,
récupéré, mis à jour et finalement supprimé. Ceci montre le cycle de vie
pour un graphique de données contenant plus d'un objet. Notez que cet
exemple vide les tables compagnie et departement au démarrage, ainsi
les résultats exacts des requêtes peuvent être connus.
Vous pouvez trouvez ces exemples combinés dans un script appelé
1cd-CRUD
dans le répertoire
Scenarios
du paquetage DAS Relationnel.
Exemple 5. Une compagnie, un département - Création
Comme dans l'exemple précédent où l'on créait juste un objet de données
de compagnie, la première action après la construction du DAS
Relationnel est d'appeler
createRootDataObject()
pour obtenir l'objet racine spécial du graphique de données vide.
L'objet compagnie est alors créé en tant que fils de cet objet racine,
et l'objet departement en tant que fils de l'objet compagnie.
Lorsqu'il est venu le temps d'appliquer les changements, le DAS Relationnel doit
effectuer des traitements spéciaux pour maintenir la clé étrangère qui
supporte les relations contenues, en particulier si une clé
primaire générée automatiquement est en jeu. Dans cet exemple, les
relations entre la clé primaire générée automatiquement
id
dans la table compagnie et la colonne
co_id
dans la table departement doivent être maintenues. Lors de l'insertion
de la compagnie et du département pour la première fois, le DAS
Relationnel doit premièrement insérer une ligne de compagnie, ensuite
appeler la méthode de PDO
getLastInsertId()
pour obtenir la clé primaire générée automatiquement, et ensuite
ajouter la valeur à la colonne
co_id
lors de l'insertion de la ligne departement.
/************************************************************************************* * Vidage des deux tables *************************************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $pdo_stmt = $dbh->prepare('DELETE FROM COMPAGNIE;'); $rows_affected = $pdo_stmt->execute(); $pdo_stmt = $dbh->prepare('DELETE FROM DEPARTEMENT;'); $rows_affected = $pdo_stmt->execute();
/************************************************************** * Crée une compagnie avec le nom Acme et un département, département de Chaussure ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
$root = $das -> createRootDataObject();
$acme = $root -> createDataObject('compagnie'); $acme -> nom = "Acme";
Exemple 6. Une compagnie, un département - Récupération et Mise à jour
Dans ce cas, la requête SQL passé Ã
executeQuery()
exécute un inner join pour joindre les données des tables compagnie et
departement. Les clés primaires pour les tables compagnie et
departement doivent être incluses dans la requête. Le jeu de résultats
est normalisé de nouveau pour former un graphique de données normalisé. Notez
que le spécificateur de colonne est passé en troisième argument de
l'appel
executeQuery()
qui autorise DAS Relationnel de savoir quelle colonne est laquelle dans
le jeu de résultats.
Notez que la colonne
co_id
bien qu'utilisée dans la requête n'est pas requis dans le jeu de
résultats. Afin de comprendre que fait DAS Relationnel lorsqu'il
construit le graphique de données, il peut être utile de visualiser
à quoi ressemble les jeu de résultats. Bien que les données dans la
base de données sont normalisée, alors plusieurs lignes de département
peuvent pointer vers la clé étrangère d'une ligne de compagnie, les
données dans le jeu de résultats sont non-normalisée : c'est, s'il y a
une compagnie et de multiples département, les valeurs pour la
compagnie qui sont répétées à chaque ligne. Le DAS Relationnel doit
renverser ce processus et retourner le jeu de résultats dans un graphique
normalisé, avec seulement un objet compagnie.
Dans cet exemple, le DAS Relationnel examine le jeu de résultats et le
spécificateur de colonne, trouve les données pour les tables compagnie
et departement, trouve les clés primaires pour les deux et interprète
chaque ligne comme contenant des données d'un département et comme
parent compagnie. S'il n'a pas vue de données de la compagnie
auparavant (il utilise la clé primaire pour vérifier), il crée un objet
compagnie et ensuite l'objet compagnie sous lui. S'il a vu des données
pour la compagnie avant et a déjà créé l'objet compagnie, il crée
simplement l'objet departement sous lui.
De cette manière, le DAS Relationnel peut récupérer et normaliser de
nouveau les données pour de multiples compagnies et de multiples
départements sous ceux-ci.
/************************************************************** * Récupération de la compagnie et du département de Chaussure, ensuite * supprime Chaussure et ajoute IT ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
$root = $das->executeQuery($dbh, 'select c.id, c.nom, d.id, d.nom from compagnie «c, departement d where d.co_id = c.id', array('compagnie.id','compagnie.nom','departement.id','departement.nom'));
$acme = $root['compagnie'][0]; // récupère la première compagnie - sera 'Acme' $chaussure = $acme['departement'][0]; // récupère le premier département en dessous - sera 'Chaussure'
Exemple 7. Une compagnie, deux départements - Récupération et Suppression
Dans cet exemple, la compagnie et le département sont récupérés et
ensuite supprimés. Il n'est pas nécessaire de les supprimer
individuellement (bien que cela est possible) - la suppression de
l'objet compagnie du graphique de données supprime aussi tous les
départements sous lui.
Notez le moyen de l'objet compagnie est actuellement supprimé en
utilisant l'appel unset de PHP. La suppression doit être effectuée
sur la propriété qui est dans ce cas la propriété de compagnie sur
l'objet racine spécial. Vous devez utiliser :
<?php unset($root['compagnie'][0]); ?>
et non pas :
<?php unset($acme); // FAUX ?>
La suppression de
$acme
détruira simplement la variable mais laissera les données dans le
graphique intacte.
/************************************************************** * Récupération de la compagnie et du département IT, ensuite supprime la * compagnie entière ***************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata);
$root = $das->executeQuery($dbh, 'select c.id, c.nom, d.id, d.nom from compagnie c, departement d where d.co_id = c.id', array('compagnie.id','compagnie.nom','departement.id','departement.nom'));
Les exemples suivant utilisent tous trois tables de la base de données
compagnie : les tables compagnie, departement et employe. Elles
introduisent le dernier morceau du fonctionnement non expliqué dans les
exemples ci haut : la référence non contenue
employe_du_mois.
Comme les exemples ci haut pour la compagnie et le département, la série
d'exemples illustre le cycle de vie complet d'un graphique de données.
Exemple 8. Une compagnie, un département, un employé - Création
Dans cet exemple, une compagnie est créée contenant un département et
seulement un employé. Notez que dans cet exemple, les trois tables sont
vidées à leur démarrage ainsi les résultats exacts des requêtes peuvent
être connus.
Notez comment une fois que la compagnie, le département et l'employé
est créé que la propriété
employe_du_mois
de la compagnie peut être faite pour pointer au nouvel employé.
Puisque c'est une référence qui n'est pas contenue, ceci ne peut être
effectué tant que l'objet employé ait été créé dans le graphique. Les
références non contenues doivent être gérées prudemment. Par exemple,
si un employé est maintenant supprimé de son département, il ne serait
pas correcte d'essayer de sauver le graphique sans premièrement
effacer ou réassigner la propriété
employe_du_mois
.
Cette règle des graphiques de données SDO requière que tous les objets
pointé par une référence qui n'est pas contenue doit être aussi
accessible par des relations contenues.
Lorsque vient le moment d'insérer le graphique dans la base de données,
la procédure est similaire à l'exemple d'insertion d'une compagnie et
d'un département, cependant, la propriété
employe_du_mois
introduit une plus grande complexité.
Le DAS Relationnel doit insérer les objets en descendant l'arbre formée
des relations contenues, donc la compagnie, ensuite le département et
ensuite l'employée. Ceci est nécessaire puisqu'il y a toujours une clé
primaire générée automatiquement du parent pour l'inclure dans une ligne
du fils. Mais lorsque la compagnie est insérée, l'employée qui est
l'employé du mois n'est pas encore inséré et la clé primaire est
inconnue. La procédure est qu'après l'insertion de l'employé et que sa
clé primaire soit connue, une dernière étape est effectuée qui permet
de modifier la compagnie avec la clé primaire de l'employé.
/************************************************************************************* * Vidage des deux tables *************************************************************************************/ $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD); $pdo_stmt = $dbh->prepare('DELETE FROM COMPAGNIE;'); $rows_affected = $pdo_stmt->execute(); $pdo_stmt = $dbh->prepare('DELETE FROM DEPARTEMENT;'); $rows_affected = $pdo_stmt->execute(); $pdo_stmt = $dbh->prepare('DELETE FROM EMPLOYE;'); $rows_affected = $pdo_stmt->execute();
/************************************************************************************* * Crée une compagnie minuscule mais complète. * Le nom de la compagnie est Acme. * Il y a un département, Chaussure. * Il y a une employé, Bob. * L'employé du mois est Bob. *************************************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata); $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
echo "Écriture de Acme avec un département et un employé\n"; ?>
Exemple 9. Une compagnie, un département, un employé - Récupération et Mise à Jour
La requête SQL passée à DAS Relationnel est cette fois un inner join
qui récupère les données des trois tables. Autrement, cet exemple
n'introduit rien de nouveau de l'exemple précédent
Le graphique est mis à jour avec l'addition d'un nouveau département et
d'un nouvel employé et quelques modifications au propriétés de nom des
objets existant dans le graphique. Les changements combinés sont écrits.
Le DAS Relationnel traitera et appliquera un mélange arbitraire des
additions, des modifications et des suppressions provenant et allant
vers le graphique.
/************************************************************************************* * Trouve la compagnie encore et change certains aspects. * Change le nom de la compagnie, le département et l'employé. * Ajoute un second département et un nouvel employé. * Change l'employé du mois *************************************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata); $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$root = $das->executeQuery($dbh, "select c.id, c.nom, c.employe_du_mois, d.id, d.nom, e.id, e.nom " . "from compagnie c, departement d, employe e " . "where e.dept_id = d.id and d.co_id = c.id and c.nom='Acme'", array('compagnie.id','compagnie.nom','compagnie.employe_du_mois', 'departement.id','departement.nom','employe.id','employe.nom')); $acme = $root['compagnie'][0];
$acme->employe_du_mois = $billy; $das -> applyChanges($dbh, $root); echo "Écriture de la compagnie avec un département en plus et un employé et tous les noms ont changés Megacorp/Footwear/Suzan)\n";
?>
Exemple 10. Une compagnie, deux départements, deux employés - Récupération et Suppression
La compagnie est récupéré en tant qu'un graphique de données complet
contenant cinq objets de données - la compagnie, deux départements et
deux employés. Ils sont tous supprimés en supprimant l'objet compagnie.
La suppression d'un objet du graphique supprime tous les objets sous
celui-ci dans le graphique. Cinq requêtes DELETE SQL sera générées et
exécutée. Comme d'habitude, elles seront qualifiées avec une clause
WHERE qui contient tous les champs qui ont été récupérés, alors toutes
les mises à jour des données dans la base de données pendant ce temps
par un autre processus seront détectées.
/************************************************************************************* * Maintenant lit une ou plusieurs fois et supprime. * Vous pouvez supprimer par partie, appliquer les changements, et ensuite * continuer à travailler avec le même graphique de données mais la précaution * est requise pour garder véracité - vous ne pouvez pas supprimer l'employé * qui est l'employé du mois sans le réassigner. Pour plus de précaution ici, * nous supprimons la compagnie en entier d'un seul coup. *************************************************************************************/ $das = new SDO_DAS_Relational ($database_metadata,'compagnie',$SDO_containment_metadata); $dbh = new PDO(PDO_DSN,DATABASE_USER,DATABASE_PASSWORD);
$root = $das->executeQuery($dbh, "select c.id, c.nom, c.employe_du_mois, d.id, d.nom, e.id, e.nom " . "from compagnie c, departement d, employe e " . "where e.dept_id = d.id and d.co_id = c.id and c.nom='MegaCorp';", array('compagnie.id','compagnie.nom','compagnie.employe_du_mois', 'departement.id','departement.nom','employe.id','employe.nom')); $megacorp = $root['compagnie'][0];
Vous pouvez être intéressé de voir les requêtes SQL qui sont générées afin
d'appliquer les changements à la base de données. Dans le haut du fichier
SDO/DAS/Relational.php,
vous trouvez un certain nombre de constantes qui contrôle si le processus
de construction et d'exécution des requêtes SQL doivent être suivies.
Essayez la configuration
DEBUG_EXECUTE_PLAN
à TRUE pour voir les requêtes SQL générées.
Le DAS Relationnel fournit deux classes : le DAS Relationnel lui-même et
aussi la sous-classe Exception qui peut être jetée. Le DAS Relationnel a
quatre appels publics utiles : le constructeur, la méthode
createRootDataObject()
pour obtenir l'objet racine d'un graphique de données vide, la méthode
executeQuery()
pour obtenir le graphique de données contenant les données d'une base de
données relationnelle et la méthode
applyChanges()
pour écrire les changements effectués au graphique de données vers la base
de données relationnelle.
__construct
- construit le DAS Relationnel avec le modèle dérivé des méta-données
passées
createRootDataObject
- obtient le graphique de données vide contenant seulement l'objet
racine spécial
executeQuery
- exécute une requête SQL passée en tant que chaîne de caractères littérale et
retourne les résultats dans un graphique de données normalisé
executePreparedQuery
- exécute une requête SQL passée en tant que requête préparée, avec
une liste de valeur à substituer pour les paramètres fictifs et
retourne le résultats d'un graphique de données normalisé
applyChanges
- examine les changements dans le graphique de données et applique
ces changements à la base de données, sujet d'une acceptation de
simultanéité optimiste
Est une sous-classe de la classe PHP
Exception.
Elle n'ajoute aucun comportement Ã
Exception.
Jetée, avec une explication utile, pour signaler les erreurs dans les
méta-données ou des échecs non prévus pour exécuter des opérations SQL.
SDO_DAS_Relational::createRootDataObject --
Retourne un objet racine spécial d'un graphique de données vide. Utilisé
lors de la création d'un graphique de données à partir de zéro.
SDO_DAS_Relational::executePreparedQuery --
Exécute une requête SQL passée comme requête préparée, avec une liste de
valeurs à substituer pour les paramètres fictifs, et retourne les résultats
comme un graphique de données normalisé.
SDO_DAS_Relational::executeQuery --
Exécute une requête SQL donnée à une base de données relationnelle et
retourne les résultats comme graphique de données normalisé.