Løbeseddel 7: Kommentarservice - databasetransaktioner via web-forms

for Database-støttet Web-publicering, efterår 2001

af Martin Elsman, redigeret af Niels Hallenberg sidst rettet 15. oktober, 2001


I denne øvelse skal du konstruere en kommentarservice, som giver læsere af dine sider på Internettet mulighed for at kommentere siderne. Servicen implementeres på maskinen hug.it.edu, men der er mulighed for at siderne der kommenteres er placeret andre steder på Internettet. Øvelsen er opdelt i fire opgaver:
  1. Konstruktion af datamodel og indsættelse af testdata
  2. Mulighed for visning af kommentarer
  3. Mulighed for indtastning af nye kommentarer
  4. Mulighed for sletning af kommentarer (ved brug af password)

Den første opgave handler udelukkende om SQL og om oprettelse af data i Oracle-databasen på hug.it.edu. De tre sidste opgaver har til formål at tilgå databasen via en browser på Internettet. Du skal skrive SQL-kommandoer (transaktioner), som via Tcl-programmer på webserveren sendes til Oracle-databasen. Tilsvarende skal du skrive Tcl-kode til HTML-formatering og visning i en browser af eksisterende data i databasen.

Servicen virker ved, at du indsætter et link på de HTML sider som skal kommenteres. Linket indeholder en form-variabel url der angiver den side kommentarerne vedrører. Denne url gemmes i databasen sammen med kommentarerne, således at alle kommentarer er knyttet op på en og kun en url.

Det er vigtigt at forstå, at denne kommentar-service kan håndtere kommentarer for et vilkårligt antal HTML-sider!

Denne løbeseddel skal være besvaret elektronisk på hug.it-c.dk senest tirsdag d. 30. oktober klokken 09.00 og i CourseGrader.

Spørgeskema

Vi vil gerne høre din mening om kurset: kursusindhold, undervisningsmateriale og undervisningsform.

Vi har derfor lavet et lille spørgeskema til kurset, som du meget gerne må udfylde.

Her er fire gode grunde til at udfylde skemaet:

Spørgsmålene supplerer de spørgsmål, som der stilles ved den generelle evaluering af kurser på IT-C, som starter i næste uge.

Opgave A (20 procent) - Datamodellen

Formålet med denne opgave er at konstruere datamodellen for kommentarservicen. Datamodellen skal bestå af en enkelt tabel comments til bruger-indtastede kommentarer knyttet til html-sider. Tabellen skal have følgende kolonner:

Du skal nu oprette comments-tabellen i Oracle-databasen. Login på hug.it.edu med ssh og start SQL*Plus med shell-kommandoen sql. Indtast nu din create table-kommando.

Inden du fortsætter med øvelsen skal du indsætte en kommentar i tabellen - udskift portnummer 8013 i url'en med dit portnummer:

  insert into comments (id, url, insertdate, name, email, text)
  values (1, 'http://hug.it.edu:8013/index.html', sysdate, 
          'Niels Hallenberg', 'nh@it.edu', 'Great page!');

Oracle-funktionen sysdate returnerer dagsdato.

Efter du har oprettet tabellen og indsat en kommentar i den er det nødvendigt at du udfører SQL-kommandoen commit fra din SQL*Plus prompt; herved sikrer du at effekten af dine SQL-kommandoer kan ses af web-serveren og andre SQL*Plus vinduer:

  SQL> commit;
  Commit complete.
  SQL>

Som besvarelse af opgaven skal du gemme din create table-kommando og din version af insert-kommandoen i filen /web/login/www/oevelse7/comments.sqlhug.it.edu.

Endelig skal du give mindst 4 bud på fornuftige legale transaktioner på datamodellen. Opskriv dine bud i form af eksempler på SQL-kommandoer og gem disse sammen med beskrivende kommentarer i slutningen af filen /web/login/www/oevelse7/comments.sqlhug.it.edu. Du bør f.eks. overveje følgende transaktioner:

Note: Kommentarer i SQL-filer skrives således:
  -- Dette er en SQL-kommentar
  -- SQL-kommentarer ignoreres når de læses af SQL*Plus

Ved at skrive kommentarer således i dine SQL-filer er det muligt at benytte SQL*Plus's @-kommando til at indlæse SQL-filen:

  SQL> @/web/login/www/oevelse7/comments.sql

Opgave B (30 procent) - Visning af kommentarer

Du skal nu konstruere en web-transaktion - i form af en tcl-fil comments.tcl - til visning af kommentarer i databasen tilhørende en bestemt url. Tcl-filen comments.tcl har til formål at hente indholdet af tabellen comments ud af databasen og vise dette indhold i form af HTML-kode, som sendes tilbage til brugerens browser.

Tcl-filen forventer en form-variabel url som angiver de kommentarer som skal returneres.

Kommentarerne ønskes opstillet som en ikke-numereret liste. Her er en skabelon til filen:

  # Set the form variable `url' - the url for the page for 
  # which we want the comments
  set_form_variables 0

  # Check the validity of the url-address
  # ...

  # Get a database handle
  set db [ns_db gethandle]

  # The select-query
  set query "select id, url, ...
             from ... 
             where url = ..."

  # Perform the query
  set selection [ns_db select $db $query]

  # Loop through the rows     
  set comments ""
  while { [ns_db getrow $db $selection] } {
    # make it possible to refer to the column names 
    # as tcl-variables
    set_variables_after_query

    # Append a comment to the tcl-variable 'comments'
    append comments "<li> ... \n"
  }
   
  # Return a page with the comments to the user - the perfect
  # solution returns a message ``no reader comments'' if there are 
  # no comments associated with the page
  ns_return 200 text/html "<html>...</html>"

Du bør anvende info exists og regexp til at checke syntaksen af form-variablen url. I tilfælde af, at du returnerer en fejl-side til brugeren, da skal du huske return efter at du har anvendt ns_return ...:

  if {![info exists ..] || ![regexp ...]} {
    ns_return 200 text/html "Error: ..."
    return
  }

Du bør returnere en passende tekst i det tilfælde, at der ikke er nogen kommentarer til den angivne url.

Gem filen comments.tcl i biblioteket /web/login/www/oevelse7/hug.it.edu og indsæt et link til filen fra bunden af din index.html-side på hug.it.edu:

  <center>
  <a href="http://hug.it.edu:8013/oevelse7/comments.tcl?url=http://hug.it.edu:8013/index.html">Readers Comments</a>
  </center>

Det skulle nu være muligt via din index.html-side at se kommentaren som du indsatte i tabellen tidligere i opgaven.

Jeg har for eksemplets skyld, oprettet en kommentar service til dette opgavesæt.

Opgave C (30 procent) - Indsættelse af kommentarer

Vi skal nu give læsere af din index.html-side mulighed for at indsætte kommentarer til siden. Opgaven deler sig i tre dele:

  1. Ændring af comments.tcl til at give mulighed for indtastning af en kommentar.
  2. Oprettelse af en Oracle-sequence til generering af unikke heltal.
  3. Konstruktion af en tcl-fil comments_add.tcl til opdatering af databasen ved indtastning af en kommentar.

Ændring af comments.tcl

Inden du starter på opgaven kopier da filen /web/login/www/oevelse7/comments.tcl til filen /web/login/www/oevelse7/comments_backup.tcl.

Du skal nu indsætte en form i filen /web/login/www/oevelse7/comments.tcl med formfelter til indtastning af email-adresse, navn og den egentlige kommentar. Filen comments_add.tcl bruges som action for formen.

Formen skal have følgende input-felter:

Se eventuelt tegningen i opgave D eller mit eksempel.

Oprettelse af en Oracle-sequence

For nogle af de senere opgaver er det nødvendigt at kunne identificere en specifik kommentar; bemærk, at der kan være flere kommentarer knyttet til en enkelt HTML side. Hertil skal vi bruge Oracles mulighed for at generere et unikt nummer, som knyttes til en kommentar når denne indsættes i databasen; vi har ikke brugt meget tid på dette til forelæsningerne, men det er ikke svært.

Indsæt følgende SQL-kode i din fil /web/login/www/oevelse7/comments.sqlhug.it.edu:

  create sequence comment_sequence start with 2;

Udfør også sql-sætningen i SQL*Plus på hug.it.edu og afslut med

  SQL> commit;
  Commit complete.
  SQL>
Sekvensen giver os mulighed for i Oracle at skrive:
  comment_sequence.nextval
som returnerer et unikt tal, der ikke tidligere har været anvendt.

Tcl-filen comments_add.tcl

Filen comments_add.tcl forventer name, email, text og url som form-variable, og skal indsætte dem i tabellen comments, således at kommentaren er registreret til HTML siden angivet ved url.

Konstruer filen comments_add.tcl udfra følgende skabelon:

  # set the form variables `name', `email', `text', and `url'

  # The procedure `set_the_usual_form_variables' works as the procedure
  # `set_form_variables' except that it also provides versions of the
  # variables where all occations of "'" in the values are exchanged
  # with "''"; these versions of the variables are named with QQ
  # preceeding the variable name and are useful because Oracle needs to
  # be fed "''" when we really mean "'". Thus if a form variable myvar
  # contains "O'Brian", the variable QQmyvar contains "O''Brian".

  set_the_usual_form_variables 0

  # Test the content of the form variables
  # ...

  # Get a database handle
  set db [ns_db gethandle]

  # The query
  ns_db dml $db "insert into comments (id, url, ..., text, insertdate)
                 values (comment_sequence.nextval, '$url', ..., '$QQtext', sysdate)"

  # Redirect to the Show-comments page
  ns_returnredirect "comments.tcl?url=$url"
Du bør anvende info exists og regexp til at checke dine form-variable.

Bemærk, hvorledes vi anvender ns_returnredirect til at returnere resultatet af comments.tcl, dvs en opdateret liste af kommentarer, som også inkluderer den vi lige har indsat.

Gem filen i biblioteket /web/login/www/oevelse7/hug.it.edu.

Afprøv muligheden for at indsætte kommentarer.

Opgave D (20 procent) - Sletning af kommentarer

I denne opgave skal du ved brug af en simpel password-mekanisme gøre det muligt for dig som administrator at slette kommentarer til en side. Her er en skitse over udvidelsen:
Det første link "Readers Comments" er et link til comments.tcl med url lig den HTML side som kommenteres.

Boksen til højre viser resultatet af comments.tcl, hvor man bl.a. har mulighed for at klikke på linket delete. Linket kalder Tcl-programmet delete_form.tcl med form-variablene url og id; dvs. unik information på den kommentar som ønskes slettet.

Tcl-programmet delete_form.tcl returnerer en HTML side med en form, hvor de to form-variable url og id er skjulte samt med mulighed for at indtaste et password. Formen kalder Tcl-programmet delete.tcl, som checker at passwordet er korrekt, og hvis det er tilfældet sletter kommentaren angivet ved url og id.

Start med at ændre filen comments.tcl således at der udskrives et delete-link sammen med hver kommentar. Linket kan passende se således ud i tcl-koden:

  <a href=\"delete_form.tcl?url=$url&id=$id\">delete</a>
Herefter skal du konstruere en fil delete_form.tcl, som skal spørge brugeren om et password, og en fil delete.tcl, som skal teste om det indtastede password er korrekt og i så fald slette den udvalgte kommentar; herefter skal delete.tcl redirigere brugeren til kommentarsiden.

Filen delete_form.tcl

Her følger en skabelon til filen:
  # set the form variables `url' og `id'
  set_form_variables 0

  # Testing of form-variables
  # ...

  # Returning a page to the user
  ns_return 200 text/html "
    <html>
    <head><title>Comment Service Password Request</title></head>
    <body bgcolor=white>
    <h2>Comment Service Password Request</h2>
    To delete the comment enter the administrator password:
    <form action=delete.tcl>
      <input type=password name=password>
      <input type=hidden name=url value=\"$url\">
      <input type=hidden name=id value=$id>

<input type=submit value=\"Delete Comment\"> </form> <hr> ... </html>

Du bør anvende info exists og regexp til at checke dine form-variable.

Filen delete.tcl

Formålet med filen delete.tcl er at foretage den endelige sletning af kommentaren identificeret ved form-variablen id. Inden kommentaren slettes undersøger vi om passwordet der blev indtastet passer med et du beslutter dig for. Her er en skabelon til filen delete.tcl:
  # set the form variables `id', `url', and `password'
  set_form_variables 0

  # Test of form variables
  # ...

  if { $password != "--your password--" } {
    ns_return 200 text/html "The password you entered is incorrect..."
    return
  }

  # The password is correct - get a database handle and do the deletion
  set db [ns_db gethandle]
  ns_db dml $db "delete from comments where ..."

  # Redirect the user to the comments page
  ns_returnredirect "comments.tcl?url=$url"
Du bør anvende info exists og regexp til at checke dine form-variable.

Gem filerne i biblioteket /web/login/www/oevelse7/hug.it.edu.

Du kan indsætte og slette kommentarer på denne kommentar service, idet passwordet er yes!!. Bemærk dog, at jeg ikke har gjort noget særligt ud af mine fejl-sider.

Husk at teste dine filer.


nh@it.edu