Toteutus Sahara-ryhmä Helsinki 22.8.2005 Ohjelmistotuotantoprojekti HELSINGIN YLIOPISTO Tietojenkäsittelytieteen laitos
Kurssi 581260 Ohjelmistotuotantoprojekti (6 ov) Projektiryhmä Sanna Keskioja Sampo Lehtinen Hanna Liedenpohja Seppo Syrjänen Asiakas Joni Salmi Johtoryhmä Juha Taina Kimmo Simola Kotisivu http://www.cs.helsinki.fi/group/sahara Versiohistoria Versio Päiväys Tehdyt muutokset 0.1 17.8.2005 Ensimmäinen versio. Tietokanta-asioita mukaan./ss
Sisältö i 1 Johdanto 1 1.1 Ei tullut takkia - tuli housut......................... 1 1.2 Dokumentin rakenne............................ 1 1.3 Termit.................................... 1 2 Tiedostojen sijainti 5 3 Tuettu laite- ja ohjelmistoympäristö 6 4 Alustustiedostot 7 5 8 6 Algoritmit 9 6.1 Yksilötapaamiset.............................. 9 6.2 Ryhmätapaamiset.............................. 9 7 Tietokannan toteutus 11 7.1 Tietokannan abstrahointi.......................... 11 7.2 Taulut.................................... 11 7.3 Indeksit................................... 13 7.4 Eheystarkistukset.............................. 13 7.5 Proseduurit ja triggerit........................... 13
1 Johdanto 1 Tanja-järjestelmän toteutusdokumentti kuvaa yksityiskohtaisesti miten järjestelmä on toteutettu. 1.1 Ei tullut takkia - tuli housut Toteutettu järjestelmä poikkeaa useassa kohdassa merkittävästi suunnitteludokumentissa 1.8.2005 pidettyssä kokouksessa projektiryhmä päätti, että käytössä olevat resurssit ja aika eivät riitä sovelma/web Start -tyyppisen kokonaan graafisen sovelluksen tuottamiseen Javalla. Tanja-järjestelmä päätettiin toteuttaa tekniikoilla, joilla käytössä olevan ajan puitteissa on mahdollista tehdä tärkeimmät vaatimukset toteuttava sovellus. Asiakkaan kanssa sovittiin.8.2005 vaatimusten uudelleenpriorisoinnista sekä toteutettavan sovelluksen ominaisuuksien supistamisesta. Tanja-järjestelmää lähdettiin toteuttamaan web-käyttöliittymällä PHP-kielellä heti 2.8.2005. Käyttöliittymän ulkoasu ja muu perustoiminta voitiin pitää vaatimusdokumentin mukaisena, vain erilaiset hiirellä maalaamiset jouduttuun korvaamaan alkeellisemmilla käyttötavoilla web-käyttöliittymän (HTML, JavaScript) rajoituksellisuuden vuoksi. Sovelluksen perusrakenteen suunnitteli Hanna vaatimusdokumentin käyttöliittymäsuunnitelmien mukaan. Tietokannan abstrahoitiin otettiin käyttöön Sepon tuntema PHP-luokkakirjasto. Yksilötapaamisaikataulun muodostusalgorimi portattiin suoraan Javalla tehdystä referenssitoteutuksesta.. 1.2 Dokumentin rakenne 1.3 Termit Toteutusdokumentissa käytetyt termit. Uudet, EHKÄ POISTUVAT termit on ilmaistu +- merkillä. CSV, Comma Separated Values, pilkkuerotetut arvot Tiedonsiirtomuoto, jota käytetään osallistujen tietojen tuontiin leikepöydän kautta esim. Kurki-järjestelmästä. Ehdotettu aikataulu Järjestelmän muodostama aikataulu, joka perustuu kutsujan kutsujan määrittelemiin aikataulun ominaisuuksiin ja osallistujien antamiin sopivuustietoihin. +Järjestelmä Tanjan ohjelmiston (asiakas ja sovelluspalvelin) sekä tietokannan muodostama toiminnallinen kokonaisuus. Kurki-järjestelmä Laitoksen kurssikirjanpitojärjestelmä.
Kutsuja Henkilö, joka haluaa tavata muita henkilöitä eli osallistujia itselleen sopivina ajankohtina. Käyttäjä Kutsuja tai osallistuja, joka käyttää järjestelmää jollain käyttöliittymällä. Lopullinen aikataulu Kutsujan hyväksymä aikataulu, joko järjestelmän alun perin ehdottama aikataulu tai kutsujan itse muokkaama aikataulu. Muokattu aikataulu Ehdotettu aikataulu, johon kutsuja on tehnyt haluamiaan muutoksia. +Ohjelmisto Tanja-järjestelmän sovellukset: asiakas ja sovelluspalvelin. Osallistuja Henkilö, jonka kutsuja haluaa tavata. Osallistujan sopivuudet kutsujan määritteleminä aikoina syötetään järjestelmään. +RPC (Remote Procedure Call) Sovellusteknikka, jossa sovelluksen eri osat suoritetaan verkon kautta saavutettavissa toisissa koneissa. Ryhmä Kutsujan määrittelemä kokonaisuus, joka sisältää osallistujat sekä yhden tai useampia aikatauluja. Ryhmätapaaminen Ryhmän yhteinen tapaaminen, johon mahdollisimman moni ryhmän osallistujista osallistuu. Sopivuus Osallistujan tapaamisajoille annettu sopivuusarvo, "prioriteetti". Arvot ovat "Sopii hyvin", "Sopii kohtalaisesti"ja "Ei sovi". Järjestelmä käyttää myös arvoa "Ei tietoa"kuvaamaan sitä, että tietyltä osallistujalta ei ole tiedossa sopivuutta kyseiselle ajankohdalle. +Sovellus Tanja-järjestelmän asiakas- tai palvelinohjelma. Tapaaminen Osallistujalle tai ryhmätapaamiselle valittu aika. Tapaamisen kesto Kutsujan valitsema yhden tapaamisen kesto. Vaihtoehdot ovat 10, 20, 15, 30, 45, 60 tai 120 minuuttia. Tapaamisen tyyppi Yhteen aikatauluun kuuluvien tapaamisten tyyppi. Aikataulu voi olla tyypiltään ryhmätapaaminen tai yksilötapaaminen. Tarjottu aika Kutsujan määrittelemä yksittäinen ajankohta (aloitus- ja lopetusaika), jolloin hän haluaa tavata ryhmänsä osallistujia. Tarjottu aika sijoittuu tiettyihin viikonpäiviin tiettynä aikataulun määrittelemänä viikkojaksona. Vanhentunut aikataulu Aikataulu, jonka viikkojakso on jo päättynyt, mutta jota ei vielä ole poistettu järjestelmästä. Viikkojakso Kutsujan kalenterista valitsemat viikot, joiden aikana ryhmän tietty aikataulu on voimassa. 2
Yksilötapaaminen Tapaaminen, jossa kutsuja tapaa henkilökohtaisesti yhden osallistujan. +XML (extensible Markup Language) Metakieli rakenteellisen tiedon kuvaamiseen. +XML-RPC Hajautettuissa verkkosovelluksissa käytetty RPC-toteutus (Remote Procedure Call), jossa metodikutsut toteutetaan HTTP-protokollan avulla vaihdettavilla XML-dokumenteilla. Ks. http://www.xml-rpc.com 3
- 4
2 Tiedostojen sijainti 5 miten softa jakaantuu osiin
3 Tuettu laite- ja ohjelmistoympäristö 6 tietokannat, selaimet, javascript jne.
4 Alustustiedostot 7
5 8
6 Algoritmit 9 Sovelluksen mielenkiintoisimmat algorimit liittyvät aikataulujen reiluun muodostamiseen osallistujen antamien sopivuuksien perusteella. 6.1 Yksilötapaamiset Yksilötapaamista varten etsitään kullekin osallistujalle mahdollisimman toivottu tapaamisaika. Yleisessä tapauksessa ongelma palautuu klassiseen kaksijakoisen graafin maksimisovitukseen (luokkaa O(n!)), joka ratkaistaan perinteisesti Munkres-Kuhn-algoritmilla (ns. Unkarilainen algoritmi) ajassa O(n**3). Sovelluksessa käytetään Konstantinos A. Nedas:n [VIITE] Java-toteutuksesta http:// www.spatial.maine.edu/~kostas/dev/soft/munkres.htm tehtyä suoraa PHP-porttausta. PHP-modulin munkres-kuhn.php yksikkötestaus tehtiin vertaamalla kymmenen testimatriisin sovitusta referenssinä pidetyn Java-version tuottamaan sovitukseen. Munkres-Kuhn-algoritmi käsittelee matriiseita [0..n][0..m], joten sovelluksen matriisi [tarjotut ajat][osallistujat] piti muuntaa algoritmin haluamaan muotoon. Tämä tehdään funktiossa muodostaaikataulu(aid,tyyppi), joka muodostaa aikataulun ja tallettaa sen tietokantaan. Koska Munkres-Kuhn-algoritmi yksinkertaisesti maksimoi valittujen tarjottu aika - osallistuja -matriisin kokonaissumman, pitää sovelluksen antamia sopivuusarvoja painottaa vastaamaan paremmin haluttua tulosta: ei sovi -arvoille annetaan painoarvo -100, jotta niitä ei varmasti anneta kenellekään. Ei tietoa -arvoilla annetaan painoarvo 10, jotta niitä voidaan käyttää jos muita sopivuuksia ei ole tiedossa. Sopii kohtalaisesti ja sopii hyvin -arvoille annetaan painoarvot 100 ja 150. Lisäksi jokaisen tarjotun ajan painoarvoon lisätään pieni korjauskerroin log(aika)*0.01, jotta algoritmi suosii tasatilanteessa aikaisempia tapaamisaikoja. Aika ilmoitetaan sekunteina maanantain keskiyöstä, joten logaritmi sijoittuu välille [0,X] ja korjauskerrooin siten välille [0,X]; Painoarvoja voi muuttaa järjestelmän konfiguraatiotiedostossa asetukset/aikataulu.php. 6.2 Ryhmätapaamiset Sopivimman ajan löytämisen ryhmätapaamiseen on triviaali ongelma, jossa riitää valita halutaanko aika, joka sopii mahdollisimman monelle edes jotenkin vaiko aika, jota mahdollisimman harva on ilmoittanut ei-sopivaksi. Ero näiden välillä tulee siitä miten tulkitaan aikoja, joista ei ole tarjolla sopivuustietoa: voidaan saada useammalle sopiva aika, jos voidaan tulkita ei tietoa -sopivuus jonkinlaiseksi sopivuudeksi sen sijaan, että löydetään aika joka sopii varmasti mahdollisimman monelle. Valinta näiden laskentatapojen välillä tehdään valitsemalla konfiguraatiotiedostoon asetukset/aikat
ei tietoa -sopivuudelle nollaa suurempi painokerroin (minimoidaan ei sovi -sopivuuksien määrä) tai painokerroin nolla (maksimoidaan vain aidot tiedetyt sopivuudet). 10
7 Tietokannan toteutus 11 -tietokantakaaviot: tähän kuvat tauluista ja triggereistä Tietokannan luovat SQL-komennot ovat Tanjan asennuspaketissa tiedostossa tanja-init.sql. 7.1 Tietokannan abstrahointi Tietokantataulujen operaatiot on abstrahoitu Baglan Dosmagambetovin [VIITE] sivulla http://baglan.web.tr/personal/articles/dbhanfler.html esittelemällä tekniikalla. Tauluja käsitellään PHP:n luokkamuuttujien ilmentyminä, jolloin rutiiniioperaatioiden tekemiseen ei tarvita sovellukseen kirjoitettavaa SQL-koodia. Alkuperäinen db.abstraction.php oli toteuttu MySQL-ohjelmistolle, mutta siitä saatiin käyttöön Sepon aikaisemmin PostgreSQL:lle porttaama versio. Myös pääluokkaa db.handle.php oli kehitetty huomattavasti yo. sivun esittämästä versiosta (mm. avainkentän nimien korvaaminen perittävissä luokissa, useapien avainkenttien käyttö). Tietokantaluokkien PHP-tiedostot ovat hakemistossa tietokanta. Koska tietokantaluokat otettiin projektin käyttöön ulkopuolisena valmiina modulina, niitä ei ole projektin puitteissa erikseen testattu. 7.2 Taulut Taulut on nimetty yksikkömuotoon (KAYTTAJA, RYHMA). Merkintä =tbl:f tarkoittaa eheystarkistusta taulun tbl kentän f kanssa eli että tämä kenttä voi saada vain arvoja, jotka esiintyvät taulun tbl kentässä f. Toteutetaan CONSTRAINTmääreellä kentän luontivaiheessa: kid int constraint ryhma_kayttaja_id_check references kayttaja(kid) Tietokannan tietojen vanhenemiseen käytettävien aikaleimojen Date-tyyppi toteutetaan PostgreSQL:n timestamp with time zone -tyypillä. Varattavat aikojen alkupisteet lasketaan sekunteina maanantaista klo 00 lähtien.
Taulu KAYTTAJA Käyttäjien tiedot kid serial not null Tietokannan generoima juokseva yksikäsitteinen tunniste. Asetetaan halutuksi näin: select setval( kayttaja_kid_seq,372). etunimi varchar sukunimi varchar sposoite varchar Sähköpostiosoite. salasana varchar uusisalasana varchar Asetettu, jos salasanaa ollaan vaihtamassa. uusisposoite varchar Asetettu, jos käyttäjä on rekisteröitymässä. viimkaytto date Viimeisin käyttöaika. Päivitetään kun käyttäjä loggaa sisälle (Tanjan koodissa), käyttäjän tiedot, ryhmäjäsenyydet tai sopivuudet muuttuvat (triggereillä?). Taulu RYHMA Ryhmien tiedot rid serial Juokseva tunniste. rnimi varchar Ryhmän nimi. kid =kayttaja:kid Ryhmän kutsuja. viimkaytto date Viimeisin käyttöaika. Päivittyy triggerillä? kun ryhmän aikatauluja päivitetään. Taulu OSALLISTUMINEN Ryhmiin osallistuminen kid =kayttaja:kid Käyttäjä kid osallistuu ryhmään rid. rid =ryhma:rid Taulu AIKATAULU Aikataulujen tiedot aid serial Juokseva tunniste. rid =ryhma:rid Ryhmä, johon aikataulu liittyy. animi varchar Aikataulun nimi. alkupvm date Viikkojakson alku. loppupvm date Viikkojakson loppu. tap_kesto integer Minuutteja. tap_tyyppi integer 1=Yksilötapaaminen, 2=Ryhmätapaaminen. tila integer Aikataulun tila: 0=laskematta, 1=laskettu. ryhmatap_aika integer Ryhmätapaamiselle laskettu aika. viimlaskettu date Viimeinen laskuaika. viimkaytto date Viimeinen käyttöaika. Päivittyy triggerillä, kun aikataulun tietoja, tarjottuja aikoja tai sopivuuksia muutetaan. Taulu TARJOTTU Tarjotut ajat aid =aikataulu:aid Aikataulu, johon tarjotut ajat kuuluvat. alkuaika integer Tarjotun ajan alku sekunteina maanantaista klo 0. kid integer Aika varattu ko. käyttäjälle. Saa olla myös 0 tai NULL, joten tätä ei varmisteta eheystarkistuksella. 12
Taulu SOPIVUUS Sopivuudet aid =aikataulu:aid Aikataulu, jonka sopivuuksia käyttäjälle kid kerrotaan. kid =kayttaja:kid sopivuus int Sopivuusarvo 0-3. 0=ei tietoa, 1=ei sovi, 2=sopii kohtalaisesti, 3=sopii hyvin. alkuaika date Sopivuus alkaa tähän aikaan. 13 7.3 Indeksit SERIAL-tyyppisille avainkentille syntyvät indeksit automaattisesti. Lisäksi on luotu seuraavat indeksit:!=tee! Indeksi Taulu Kentät kayttaja_sposoite kayttaja sposoite!osallistuminen_rid_kid osallistuminen rid, kid!sopivuus_aid_kid sopivuus aid, kid!tarjottu_aid tarjottu aid 7.4 Eheystarkistukset Tietokannan eheyttä valvovat seuraavat constraint-määrittelyt: Tarkistus Taulu.kenttä Taulu(kenttä) ryhma_kid_check ryhma.rid kayttaja(kid) aikataulu_ryhma_rid_check aikataulu.rid ryhma(rid) osallistuminen_kayttaja_kid_check osallistuminen.kid kayttaja(kid) osallistuminen_ryhma_rid_check osallistuminen.rid ryhma(rid) sopivuus_aikataulu_aid_check sopivuus.aid aikataulu(aid) tarjottu_aikataulu_aid_check tarjottu.aid aikataulu(aid) sopivuus_kayttaja_kid_check sopivuus.kid kayttaja(kid) 7.5 Proseduurit ja triggerit Tietokantaan on määritelty seuraavat PLPSQL-proseduurit. Nimi Lähdetaulut Kohdetaulut Tarkoitus touch() kayttaja, ryhma, aikataulu kayttaja, ryhma, aikataulu Virkistää muutetun rivin viimka touchuser() tarjottu, sopivuus kayttaja Virkistää käyttäjän viimkaytto-k touchtt() tarjottu, aikataulu aikataulu Nollaa aikataulun tila-kentän til