N d anonymat : page 1 LI345 - EXAMEN DU 22JUIN 2010 Durée : 2h ---documents autorisés Transactions Soit la relation Produit, et les deux transactions T1 et T2 suivantes : Produit NOM PRIX P1 40 P2 50 P3 60 2 pts T1 : Begin Transaction Update PRODUIT set PRIX=22 where NOM = P1 ; Insert into PRODUIT values ( P4, 0) ; Update PRODUIT set PRIX = 38 where NOM= P1 ; Commit ; T2 : Begin transaction Set transaction isolation level serializable Select avg(prix) as prix-moyen FROM Produit ; Commit ; Ces deux transactions sont lancées presque simultanément. Quelles sont les valeurs possibles pour prixmoyen? Justifiez votre réponse. T2 doit être exécutée soit entièrement avant T1, soit entièrement après. Si T2 s exécute avant T1, la valeur de prix-moyen est 50 (moyenne de 40, 50, 60 ). Si T2 s exécute après T1, la valeur de prix-moyen est 37 (moyenne de 38, 50, 60 et 0).; Autorisations On considère 4 utilisateurs, nommés A, B, C, et D. A est propriétaire de la relation R. Soit P un privilège. On effectue les actions suivantes : N Utilisateur Action 1. A : GRANT P ON R TO B WITH GRANT OPTION 2. A : GRANT P ON R TO D WITH GRANT OPTION 3. B : GRANT P ON R TO C WITH GRANT OPTION 4. C : GRANT P ON R TO B WITH GRANT OPTION 5. D : GRANT P ON R TO C 6. A : REVOKE P ON R FROM B CASCADE 7. A : REVOKE P ON R FROM D RESTRICT Après cette série d actions, quelles sont les utilisateurs qui possèdent le privilège P sur R? Justifiez votre réponse. 1 pt
page 2 A, C et D ont le privilège P (le dernier revoke ne fait pas d effet, car D l a transmis à C. Il ne se passe donc rien.) SQL3 : 7 Pts On considère le schéma relationnel objet suivant : Create type Menu as object ( Nom varchar (20), Prix Number (2) ) ; Create type EnsMenu as table of Menu ; Create type Adresse as objet ( Numero number(3), Rue varchar2(30), Cp number(5) ); create type restaurant as object ( nom varchar2(30), adr Adresse, lesmenus EnsMenu ); Create type EnsRestaurant as table of restaurant; Create type Musee as object( Nom varchar(20), Adr Adresse, JourFermeture varchar(15) ) ; Create type EnsMusees as table of Musee; Create type Ville as object ( Nom varchar2(30), Lesrestos Ensrestaurant, Lesmusees EnsMusees ); Create table lesvilles of Ville Nested table lesrestos sotre as tabresto (nested table lesmenus store as tabmenus), Nested table lesmusees store as tabmusee; Question 1. Donnez l instruction nécessaire pour insérer la ville de Paris, avec un restaurant qui s appelle Train bleu, situé 20 bd Diderot, 75012, et qui a un menu dégustation à 50.
page 3 Insert into LesVilles values Ville( Paris, EnsRestaurant ( restaurant ( train bleu, Adresse (20, bddiderot, 75012), EnsMenu (Menu( degustation, 50)) ) ) EnsMusees() ) ; Question 2. Donnez l instruction qui permet d insérer dans la ville de Paris, le musée Rodin, situé 77 rue de Varenne, 75007. Ce musée ferme le mardi. Insert into table (select v.lesmusees from LesVilles v where v.nom= Paris ) values Musee ( Rodin, Adresse (77, rue de Varenne, 75007), mardi ) ; Question 3. Donnez l expression en SQL3 des requêtes suivantes : 1. Nom des villes ayant un musée ouvert le lundi. Select v.nom from LesVilles v, table(v;lesmusees) m where m.jourfermeture <> lundi ; 2. Nom et adresse d un restaurant à Paris où on peut manger pour moins de 30 Select r.nom, r.adr.numero, r.adr.rue from LesVilles v, table (v.lesrestos) r, table (r.lesmenus) m where m.prix <30 ; 3. Nom des restaurants de Paris qui sont dans le même arrondissement que le musée Rodin.
page 4 Select r.nom from LesVilles v, table (v.lesrestos) r, table (v.lesmusees) m Where m.nom= Rodin and m.adr.cp= r.adr.cp Question 4. On veut compléter le schéma en ajoutant des lieux de spectacle, qui peuvent être des cinémas et des théâtres. Un lieu de spectacle a un nom et une adresse. Pour chaque cinéma, on indique le programme. Pour un théâtre, on donne le titre de la pièce, le nom du metteur en scène et une liste d acteurs. En utilisant les types définis ci-dessous (et l ensemble du schéma défini dans la question 1), définissez les éléments de schéma nécessaires pour prendre en compte ces nouvelles informations : Create type programme as object ( Titre varchar2(50), Salle number(2), Séances varchar2(30) ); Create type acteurs as table of varchar2(30); Create type LieuSpectacle as object ( ) not final; Nom varchar2(20), Adr Adresse Create type cinema under LieuSpectacle (prog programme) ; Create type theatre under LieuSpectacle (titre varchar2(20), mes varchar2(20), act acteurs); Question 5 Donnez la nouvelle définition du type Ville, intégrant ces informations. Drop type Ville force ; Create type Create type LesLieux as table of LieuSpectacles ; Create type Ville as object ( Nom varchar2(30),
page 5 Lesrestos Ensrestaurant, Lesmusees EnsMusees, Spectacles LesLieux); XML-DTD-XSLT 5 pts Le site Fliquaire permet à ses utilisateurs de publier des photos sur le Net. Tous les utilisateurs du Site ont un identifiant, ainsi qu un nom et une adresse e-mail. Les photos ont aussi un identifiant et une référence vers l utilisateur qui a «uploadé» la photo. Elles ont également un titre obligatoire, une description optionnelle et un lieu aussi optionnel. Enfin, on peut taguer des utilisateurs du Site sur les photos et aussi y ajouter des commentaires. Les commentaires peuvent être anonymes, c.-à-d. les utilisateurs peuvent poster des commentaires sur les photos même s ils ne sont pas registrés sur le Site. Chaque lieu a un identifiant qui est utilisé pour définir le lieu des photos. Finalement, chaque utilisateur Fliquaire a une liste de contacts. Ce Site Web utilise une base XML pour stocker toutes les informations dont il a besoin. Voici un petit exemple de cette base : <?xml version="1.0" encoding="utf-8"?> <!DOCTYPE fliquaire SYSTEM "fliquaire.dtd"> <fliquaire> <utilisateurs> <utilisateur id="u1"> <nom>toto</nom> <e-mail>toto@jussieu.fr</e-mail> </utilisateur> <utilisateur id="u2"> <nom>titi</nom> <e-mail>titi@jussieu.fr</e-mail> </utilisateur> </utilisateurs> <photos> <photo id="p1" proprietaire="u1"> <titre>soirée</titre> <description>blablabla</description> <url>photos.fliquaire.com/photo1.jpg</url> <personnes> <personne id="u1" /> <personne id="u2" /> </personnes> <commentaires> <commentaire de="u1">blablabla</commentaire> <commentaire>bliblibli</commentaire> </commentaires> </photo> <photo id="p2" proprietaire="u2" lieu="l1"> <titre>sagrada Familia</titre> <description>blablabla</description> <url>photos.fliquaire.com/photo2.jpg</url> </photo> </photos> <lieux> <lieu id="l1">barcelone</lieu> <lieu id="l2">paris</lieu> </lieux>
page 6 <contacts> <contact utilisateur1="u1" utilisateur2="u2" /> <contact utilisateur1="u1" utilisateur2="u3" /> </contacts> </fliquaire> Question 1. Compléter la DTD suivante selon les indications données par l énoncé pour qu elle valide le document d exemple : <!ELEMENT fliquaire (utilisateurs, photos, lieux, contacts)> <!ELEMENT utilisateurs (utilisateur*)> <!ELEMENT utilisateur... <!ATTLIST utilisateur... <!ELEMENT nom... <!ELEMENT e-mail... <!ELEMENT photos (photo*)> <!ELEMENT photo... <!ATTLIST photo...... <!ELEMENT titre... <!ELEMENT description... <!ELEMENT url... <!ELEMENT personnes (personne+)> <!ELEMENT personne... <!ATTLIST personne... <!ELEMENT commentaires (commentaire+)> <!ELEMENT commentaire... <!ATTLIST commentaire... <!ELEMENT lieux (lieu*)> <!ELEMENT lieu... <!ATTLIST lieu... <!ELEMENT contacts (contact*)> <!ELEMENT contact... <!ATTLIST contact... Réponse (2 points) <!ELEMENT fliquaire (utilisateurs, photos, lieux, contacts)> <!ELEMENT utilisateurs (utilisateur*)> <!ELEMENT utilisateur (nom, e-mail)>
page 7 <!ATTLIST utilisateur id ID #REQUIRED> <!ELEMENT nom (#PCDATA)> <!ELEMENT e-mail (#PCDATA)> <!ELEMENT photos (photo*)> <!ELEMENT photo (titre, description?, url, personnes?, commentaires?)> <!ATTLIST photo id ID #REQUIRED proprietaire IDREF #REQUIRED lieu IDREF #IMPLIED> <!ELEMENT titre (#PCDATA)> <!ELEMENT description (#PCDATA)> <!ELEMENT url (#PCDATA)> <!ELEMENT personnes (personne+)> <!ELEMENT personne EMPTY> <!ATTLIST personne id IDREF #REQUIRED> <!ELEMENT commentaires (commentaire+)> <!ELEMENT commentaire (#PCDATA)> <!ATTLIST commentaire de IDREF #IMPLIED> <!ELEMENT lieux (lieu*)> <!ELEMENT lieu (#PCDATA)> <!ATTLIST lieu id ID #REQUIRED> <!ELEMENT contacts (contact*)> <!ELEMENT contact EMPTY> <!ATTLIST contact utilisateur1 IDREF #REQUIRED utilisateur2 IDREF #REQUIRED> Question 2. Donner l expression XPath qui retourne toutes les photos dont l attribut lieu est Barcelone. Réponse (1 point) //photo[@lieu = //lieu[.="barcelone"]/@id] Question 3. Compléter la feuille XSLT ci-après pour qu elle génère à partir du document XML précédent, un autre document XML dont l élément racine est photos-des-contacts-de-toto et dont ses éléments fils sont toutes les photos de tous les contacts de Toto, c.-à-d. toutes les photos «uploadées» par les utilisateurs Y, où «contact utilisateur1=x utilisateur2=y» et X est Toto : <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> </xsl:template> </xsl:stylesheet> Réponse (1 point) <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform">
page 8 <xsl:output method="xml" indent="yes"/> <xsl:template match="/"> <photos-des-contacts-de-toto> <xsl:copy-of select="//photo[@proprietaire = //contact[@utilisateur1 = //utilisateur[nom = 'Toto']/@id]/@utilisateur2]"/> </photos-des-contacts-de-toto> </xsl:template> </xsl:stylesheet> Question 4. Compléter la feuille XSLT suivante pour qu elle génère une page HTML avec toutes les photos où Titi a été tagué, c.-à-d. toutes les photos dont les sous-éléments personne font référence à l utilisateur Titi. Cette page doit avoir le format ci-dessous : <HTML> <BODY> <P>Les photos avec Titi</P> <TABLE> <TR> <TD> <P>Soirée</P> <IMG src="photos.fliquaire.com/photo1.jpg" /> </TD> </TR> <TR>... </TR> </TABLE> </BODY> </HTML> <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="html"/> <xsl:template match="... <HTML> <BODY> </BODY> </HTML> </xsl:template> <xsl:template match="...
page 9 </xsl:template> </xsl:stylesheet> Réponse (1 point) <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/xsl/transform"> <xsl:output method="html"/> <xsl:template match="/"> <HTML> <BODY> <P>Les photos avec Titi</P> <TABLE> <xsl:apply-templates select="//photo[.//personne/@id = //utilisateur[nom = 'Titi']/@id]" /> </TABLE> </BODY> </HTML> </xsl:template> <xsl:template match="photo"> <TR> <TD> <P><xsl:value-of select="titre"/></p> <IMG> <xsl:attribute name="src"> <xsl:value-of select="url"/> </xsl:attribute> </IMG> </TD> </TR> </xsl:template> </xsl:stylesheet> PHP 5 Pts On considère un réseau social, dont les informations sont stockées dans la base RéseauSocial, contenant plusieurs tables, parmi lesquelles les tables suivantes (les clés des tables sont soulignées): Utilisateur(idu, nom, profil): informations sur les membres idu: identifiant unique de l'utilisateur nom: nom en clair profil: auto-description Attente(idr, idu, datedem): demandes d'amitié en attente idr: identifiant de l'utilisateur ayant fait la demande d'amitié
page 10 idu: identifiant de utilisateur auquel a été faite la demande datedem: date à laquelle a été faite la demande Les requêtes sur la base de données sont exécutées en utilisant la fonction DB_execSQL($req, $serv) étudiée en TD, où $req est la requête à exécuter, $serv est l'identifiant de la connexion. Question 1(1,5pt). Donnez la fonction listeattente($id, $serv) qui retourne la liste de personnes en attente pour un utilisateur $id sous forme d'un tableau php à deux dimensions. À chaque identifiant idr dans la table Attente qui a fait une demande à $id, on associe un tableau indicé contenant son nom et son profil. Si $id n'est pas valide la fonction retourne NULL. Solution: function listeattente($id, $serv) { } $req = ''select idr, nom, profil from Attente a, Utilisateur u where idr=u.idu and and a.idu=''.$id; $resultat = DB_exec_SQL($req, $serv); while($ligne = mysql_fetch_object($resultat)){ } $tab[$ligne->idr]=array($ligne->nom, $ligne->profil); if(isset($tab)) return $tab; return NULL; Question 2(1,5pt). Écrivez la fonction listeattenter($id, $tab, $serv) dont le paramètre $tab est un tableau php retourné par la fonction précédente. Pour chaque utilisateur idr dans Attente ayant fait une demande à $id depuis plus d'un mois, on ajoute dans la liste correspondante à idr dans $tab, en plus de son nom et son profil déjà existants, la valeur true. Indication: vous pouvez utiliser la fonction DATE_ADD de MySQL vue en TD.
page 11 Solution: function listeattenter($id, $tab, $serv) { } $req = ''select idr from Attente where idu=$id and NOW() > DATE_ADD(dateDem, INTERVAL 1 MONTH).; $resultat = DB_exec_SQL($req, $serv); while($ligne = mysql_fetch_object($resultat)){ } $tab[$ligne->idr][2] = true; Question 3(1,5pt). Écrivez la fonction afficheattente($tab) qui affiche sous forme d'un tableau HTML (avec deux colonnes), la liste des noms et des profils des utilisateurs du tableau $tab créé par la fonction listeattenter précédente. Pour chaque utilisateur ayant fait sa demande depuis plus d'un mois on affiche son nom en rouge.
page 12 Solution: function afficheattente($tab) { echo ''<TABLE border=1>''; echo ''<TR><TH>Utilisateurs</TH><TH>Profils</TH></TR>''; foreach($tab as $idu->$liste){ if(isset($liste[2])) echo''<tr><td><font color='red'>''.$liste[0].''</font></td></tr>''; else echo''<tr><td>''.$liste[0].''</td></tr>''; echo''<tr><td>''.$liste[1].''</td></tr>''; } echo ''</TABLE>''; } Question 4(0,5pt). Quelle méthode est-il préférable d'utiliser pour transmettre à un script PHP les informations saisies dans un formulaire HTML et pourquoi? Solution: POST est préférée car les paramètres sont transmis dans le corps du message, ce qui évite des très longues URL.