Løbeseddel 10: Webbaseret pladekartotek

for Databasestøttet Webpublicering

af Martin Elsman og Niels Hallenberg sidst rettet 15. februar, 2002


I denne øvelse skal du konstruere et webbaseret pladekartotek. Øvelsen lægger op til, at du selv udvikler datamodellen udfra nogle meget præcise retningslinier. Det er altså en del af opgaven, at du selv finder frem til de tabeller der skal anvendes. Du skal også selv finde frem til de transaktioner, som du skal anvende for at lagre og hente oplysninger på plader. Det er meget vigtigt, at du har et overblik over datamodellen og ved hvilke Tcl-filer du skal kode, samt hvilke form-variable hver Tcl-fil forventer, inden du begynder at kode den første Tcl-fil. Hvis du laver dette analysearbejde først, så minimerer du den samlede tid på opgaven. Læs hele opgaveteksten inden du begynder med den første opgave.

Øvelsen er opdelt i fire opgaver:

  1. konstruktion af datamodel
  2. opstilling af legale transaktioner
  3. tilknytning af transaktioner til web-forms (HTML-sider)
  4. konstruktion af kode til at processere ovenstående web-forms (Tcl-filer)

Pladekartoteket generelt

Du skal kunne oprette og slette plader i pladekartoteket. Det er ikke nødvendigt at kunne rette en plade i pladekartoteket. En plade består af nogle stamdata, f.eks. pladetitel samt et antal sange. Det nemmeste er at opdele oprettelse af en plade og oprettelse af sange tilknyttet en bestemt plade i to forskellige indtastningsbilleder. De følgende opgaver navigerer dig gennem de beslutninger du skal gøre, for til sidst at være i stand til at kode servicen.

Det kan betale sig, at være omhyggelig med de tre første opgaver.

Opgave A (30 procent)

Som det første led i konstruktionen af et webbaseret pladekartotek skal du konstruere en datamodel for systemet i form af en samling create table SQL-kommandoer.

For hver plade i databasen skal der som et minimum være tilknyttet en pladetitel, et kunstnernavn, et udgivelsesår og en samling sangtitler.

Det er nødvendigt at oprette mindst to tabeller; den ene tabel kan således indeholde pladetitel, kunstnernavn, udgivelsesår og et tal til at identificere en plade (f.eks. plade_id integer primary key); den anden tabel kan så indeholde tilknytninger af sangtitler til hver plade_id. Det anbefales, at man anvender et tal til at indentificere en sang (f.eks. sang_id integer primary key).

Til brug for oprettelse af nye plader i databasen skal du oprette to sekvenser (Oracle: sequence), f.eks.:

  create sequence plade_id_sequence start with 10;
  create sequence sang_id_sequence start with 10;

En datamodel, uden detaljer, kan f.eks. se således ud:

Du skal huske at overveje

  1. hvilke felter skal hver tabel indeholde. Teksten ovenfor angiver hvilke felter du har brug for
  2. hvilken type hvert felt skal have, f.eks. varchar(...) og integer
  3. hvilke felter skal være primær-nøgle i hver tabel
  4. er der nogle felter, som du synes skal udfyldes, dvs. være not null.
  5. er der nogle felter, som du synes skal være unikke udover primær-nøglerne, dvs unique
  6. om du vil anvende references.
  7. hvis du anvender drop table skal din rækkefølge være korrekt. Antag f.eks., at du anvender to tabeller tab1 og tab2, hvor tab2 refererer til tab1, dvs. databasen checker at der til alle rækker i tab2 findes refererede rækker i tab1. Så skal du slette tab2 før du sletter tab1, idet rækkerne i tab2 jo henviser til rækker i tab1.
Gem din datamodel i filen /web/login/www/oevelse10/pladekartotek.sqlhug.it.edu sammen med sql-kode for indsættelse af to pladeemner i tabellerne. Endelig skal du starte SQL*Plus på hug.it.edu ved brug af ssh og udføre sql-kommandoerne:
  SQL> @/web/login/www/oevelse10/pladekartotek.sql  
  ...
  SQL> commit;
SQL*Plus kommandoen commit sikrer at dine tabel-indsættelser bliver synlige for andre SQL*Plus vinduer og for din web-server. Det er vigtigt, at du husker commit.

Opgave B (20 procent)

I denne opgave skal du opskrive en række legale transaktioner for det webbaserede pladekartotek. Her er to eksempler på legale transaktioner:

Oprettelse af en ny plade i kartoteket (uden tilknyttede sange)

  insert into pk_plade (plade_id, titel, kunstner, aar)
  values (plade_id_sequence.nextval, 'Abbey Road', 'Beatles', '1969');

hvor jeg har kaldt tabellen med plader for pk_plade.

Tilknytning af en ny sang til en eksisterende plade

  insert into pk_sang (plade_id, sang_id, titel)
  values (38, sang_id_sequence.nextval, 'Here comes the sun');   -- 38 er plade_id for Beatles' Abbey Road

hvor alle sange er nummereret med sang_id. Jeg har kaldt tabellen med sange for pk_sang.

Som ovenfor skal du opskrive eksempler på SQL-kommandoer for følgende transaktioner:

  1. sletning af en sang fra en plade
  2. sletning af en plade fra kartoteket (du kan antage at der ingen sange er knyttet til pladen)
  3. visning af sange på en plade med et givet plade_id (select). Du skal som minimum vise pladenavn, kunstner og sangtitler.
  4. visning af alle plader udgivet af en bestemt kunstner (select). Du skal som minimum vise pladenavn, kunstner og sangtitler.

Gem SQL-kommandoerne i en fil /web/login/www/oevelse10/transaktioner.sqlhug.it.edu.

Opgave C (10 procent)

I denne opgave skal du konstruere web-strukturen for pladekartoteket. Her er en skitse af hvordan systemet kan tænkes opbygget:
Kasserne i diagrammet repræsenterer det webbaserede pladekartoteks tilstande for hvilke HTML-kode vises i en brugers browser. Pilene repræsenterer links til en ny tilstand. På hver pil skriver vi navnet på det Tcl-program, som vi kalder samt de form-variable der overføres. Nogle pile repræsenterer transaktioner for hvilke databasen opdateres (se opgave B) og brugeren ser en ændring i sin browser.

Indgangssiden til pladekartoteket er vist som en kasse øverst i diagrammet, som kan implementeres som en HTML-fil. De resterende kasser (tilstande) i diagrammet skal implementeres som Tcl-filer, da disse kasser repræsenterer dynamiske sider (d.v.s., hvad brugeren ser i sin browser afhænger af indholdet i databasen og af eventuelle form-argumenter). Du kan også vælge at lade siden "Vis alle plader" være indgangssiden.

Det er din opgave at gøre tegningen ovenfor færdig. På hver at de tre resterende pile skal du skrive navn på det Tcl-program som kaldes samt angive hvilke form-variable der overføres.

For at bestemme hvilke form-variable der skal overføres, så anbefaler jeg at du kun overfører dem der er absolut nødvendige - altså hold antallet af form-variable så lavt som muligt. Eksempelvis, hvis du skal vise sange til en plade, så er plade_id nok idet alle oplysninger om sange og plade kan hentes fra databasen. Der er ingen grund til også at overføre pladetitel, selvom at du gerne vil vise den sammen med sangene - pladetitlen findes jo i databasen.

I den vejledende løsning indgår 6 filer:

Det anbefales, at du laver en tegning svarende til den ovenfor. På alle pile skal der være annoteret en Tcl-fil samt de form-variable som overføres til Tcl-filen.

Til denne opgave skal du aflevere

  1. en HTML-fil /web/login/www/oevelse10/pladekartotek.htmlhug.it.edu, som er indgangssiden til pladekartoteket. HTML-filen skal indeholde et link til Tcl-filen for visning af alle pladeemner i databasen.

  2. en beskrivelse af din web-struktur, som indeholder navne på de Tcl-programmer pladekartoteket anvender samt, for hver Tcl-fil de form-variable som filen forventer. Dette kan enten afleveres i en tekstfil /web/login/www/oevelse10/struktur.txt, eller som en tegning svarende til den ovenfor, hvor der på alle pile er noteret både Tcl-program og de form-variable som overføres. Hvis du vælger at aflevere en tegning, så kan du evt. scanne en tegning skrevet i hånden, og overføre filen til hug.it.edu som /web/login/www/oevelse10/struktur.gif.

Opgave D (40 procent)

I denne opgave skal du konstruere Tcl-filer for de dynamiske sider og for transaktioner til sletning og oprettelse af plader og sange i databasen.

Start med at konstruere de dynamiske sider for kasserne i diagrammet. Indsæt også links i disse sider til Tcl-filerne for database-transaktionerne.

For database-transaktionerne kan du med fordel benytte Tcl-kommandoen

  ns_returnredirect url
Denne kommando returnerer en besked til browseren om at vise siden url. Her er kode til implementation af database-transaktionen for indsaettelse af en sang for en given plade i databasen:

proc return_page {plade_id} {
  ns_returnredirect "pk_vis_sange.tcl?plade_id=$plade_id"
}

# set the form variables `QQsangtitel' and `plade_id'
set_the_usual_form_variables 0

# Test plade_id og sangtitel!
if { ![info exists plade_id] ||
     ![regexp {^[0-9]*$} $plade_id]} {
  ns_return 200 text/html "Panik, der er ikke angivet en plade_id."
  return
}

if { ![info exists sangtitel] || 
     ![string length [string trim $sangtitel]]} {
  ns_return 200 text/html "Panik, der er ikke angivet en sangtitel."
  return
}

set insert_sql "insert into sangtitler (plade_id, sang_id, sangtitel)
                values ($plade_id, sang_id_seq.nextval, '$QQsangtitel')"

set db [ns_db gethandle]

ns_db dml $db $insert_sql

# instead of returning a page to the user with `thank you'
# information, we ask the browser to show the - now updated - 
# song page; notice that the dynamic page `pk_sange_vis.tcl' takes
# a form variable `plade_id' as argument.
return_page $plade_id

Bemærk at det ikke kræves af brugeren at der indtastes et password for at slette og oprette data i pladekartoteket.

Gem filerne til opgaverne ovenfor på hug.it.edu i kataloget /web/login/www/oevelse10/.


mael@it.edu, nh@it.edu