Saturday 3 November 2012

Se pidempi teksti Pröngistä

Pröng on julkaistu

Muistaakseni lupasin laajemman tekstin Pröngistä tälle viikolle. Saa nähdä ehdinkö ihan tavoitteeseeni, viikko lähentelee hälyttävästi loppuaan, ja toivon etten kirjoittele ensi viikolla ennen sunnuntaina kuin kaksi kertaa: matkalla tampereelle ja matkalla sieltä kotiin. Muuten suunnitelmananani on olla olematta kovin aktiivinen ensiviikolla internetissä syistä, joista voisi joskus olla jännä kirjoittaa. Ei kuitenkaan ensi viikolla. Ensi viikolla olen kirjoittamatta syistä, joista en halua kirjoittaa ensi viikolla, koska haluan kirjoittaa niistä ensi viikolla. Lupaava alku tekstille: tietäkää takana olevan tehokas MERPGinkehityssessio, mikä ei koskaan lupaa koherenttia tekstintuottoa. Tästäkin sen näkee: otsikko kertoo Pröngistä, ja nyt olen lähinnä mussuttanut siitä, miten en halua haluta olla haluamatta.

Julkaisin siis uuden koodin tiistaina Pröngissä. Eilen, kun Pröng joutui kehittelyjen ja saunonnan vuoksi tosikäyttöön, selvisi kaksi asiaa, jotka olemme listanneet edellisen postin kommentteihin: Luonnoksen lisäys oli rikki, ja rivinvaihtoja järjestelmä tukee taas miten jaksaa. Vanha koodi muutti luonnos-lomakkeelta saamastaan luonnoksesta \n - merkit <br> - merkeiksi, eli html-rivinvaihdoiksi, ja sen jälkeen se poisti tekstistä kaikki pelottavat html-merkinnät ja tallensi sen kantaan. Näinhän tätä ei todellakaan olisi kannattanut tehdä: mitä jos datasta ollaan kiinnostuneita Pröngin ulkopuolella? Mitä jos joskus tehdään esim. WPF-ohjelma, joka on kiinnostunut datasta, mutta ei todellakaan osaa käsitellä HTMLää. Oikea paikka pelottavien html-merkintöjen siivoamiselle olisi ollut esityskerros, eli ne olisi siivottu juuri ennenkuin ne echotetaan selaimelle.

Tästä voidaan päätellä että kannassa on rivinvaihtoja monenlaisissa muodoissa. Tästä näette oireen huonosti kohdellusta tietokannasta. Ensi viikon jälkeen pitäisi läpikäydä luonnokset käsin ja korjata tuollaiset poikkeamat. Toinen toteuttamista odottava projekti on säätää luonnoksen esittävä proseduuri muuttamaan \n - rivinvaihdot <br> - merkinnöiksi. Tallennusproseduuri tietääkseni tallentaa rivinvaihdot ihan validisti kantaan asti, mutta en ole vielä testannut, ja pyydän ettei kukaan muukaan menisi testaamaan.

Luonnosten rikkonaisuudesta vielä. Yritin lisätä Pröngiin Luonnosta 519, "Voi hitsi kun voikukkia ei voi syödä", kun kohtasin yllättävää käyttäytymistä: Se ei lisäytynyt kantaan. Ihmettelin minuutin että mitä hittoa, sitten tajusin ongelman. Joku viisas joskus kertoi miten historiaa tuntemattomat ovat tuomittuja toistamaan sitä. Olin ilmeisesti unohtanut oman historiani, sillä kuten ainakin Tässi muistaa, vanhassa Pröngissä oli koko elämänsä ajan sellainen ongelma, että kaikki LID-linkit osoittivat devpröngin puolelle. Nyt oli käynyt samoin: luonnostenlisäysformi osoitti devpröngiin! Yllättäen sessio, joka oli olemassa osoitteessa prong.viuhka.fi, ei enää ollutaan olemassa feuer.viuhka.fi:ssä, jolloin autentikointikoodi ilmoitti että tähän kantaanhan ei sitten kirjoiteta mitään.

Arkkitehtuurista

Nyt taas tuntuu siltä, että tällä arkkitehtuurilla päästään pitkälle. Perusrakenne on lopultakin aitoa MVC:tä. Frontcontroller valitsee cmd-urlparametrin perusteella asianmukaisen controllerin, joka hakee tietokannasta tarvittavan datan ja lähettää sen vapaasti valitsemalleen näkymälle. Muistaakseni haukuin PHP:n erilaisten model/ORM - toteutusten tasoa blogissa aiemmin, ja selitin suunnittelevani omaa mapper-toteutusta. Noh, minähän kirjoitin sellaisen. Pröngissä kaikki domain-oliot periytyvät Entiteetti-luokasta, joka sisältää ison mapin, johon olioiden ominaisuudet tallennetaan. Entiteetti-luokassa on myös ylikirjoitettu set() ja get() - metodit, joita kutsutaan jos PHP ei löydä oliolta sellaista kenttää, jota ohjelmoija yrittää käsitellä. Nämähän sitten asettavat ja hakevat datansa tästä mapista, jolla myös tietokannan ja XML:n teko tekeminen helpottuvat.

Tietokanta on myös kiva. PDO:n vuoksi mallikerros ei tiedä mitään käytössä olevasta tietokannasta. Olioilla on ApplyToDatabase() - metodi, joka tarkistaa löytyykö olio kannasta, ja tuloksen mukaan ohjaa sisäisen datamappinsa joko Database::Insert()ille tai Database::Update()lle. Hakuproseduurit taas ovat lispihtäviä. Database-luokalla on metodi SelectAll(), jolle annetaan tyhjä, hakukohteen tyyppinen olio parametrina, ja se hakee kaikki oliot parametrin nimeämästä taulusta. Database::SelectAll(new Luonnos()); siis palauttaa kaikki luonnokset, Database::SelectAll(new Kommentti()); kaikki kommentit, ja niin edespäin. Toinen hakuun liittyvä metdoi, Database::SelectWhere() ottaa tauluparametrin lisäksi predikaattifunktion, jonka avulla se sitten suodattaa palautettavan joukon. Esimerkiksi Database::SelectWhere(new Luonnos(), function($luonnos) {return $luonnos->LID > 300;}); palauttaa kaikki luonnokset, joiden LID on yli 300.

Näitä metodeja käytän koodissa melko vapasti. Kuten kukin voi arvata, jos jokaisen luonnoksen latauksessa läpikäydään koko tagien- ja kommenttien joukko, lähentelee operaation big-O - lukema kompleksisuutta O(MG). Sen kanssa on vain pakko elää, kunnes alan jäädyttää koodin ominaisuuksia korvaamalla Database::Select*() - kyselyjä joihinkin optimoidumpiin, ei niin dynaamisiin toteutuksiin. Kompleksisuus ei ole kuitenkaan itsessään pullonkaula. Pullonkaula on tietokanta: Arkiston lataus tuotti kuusi TUHATTA "select * from tagit" - kyselyä, mikä meni läpi kehitysserverillä juuri ja juuri naurettavien vasteaikojen kanssa, mutta jolle piti kehittää ratkaisu kun viuhkan PHP ilmoitti ettei onnistu. Helppoa: Kakutetaan ensimmäisen SELECT * FROM T - kyselyn tulokset, ja palautetaan ne, ellei parametrilla spesifioida että halutaan päästä kakun ohi kantaan. Tämä toimii, koska PHP-sivujen elinaika on sellainen, että joka sivunlatauksella aloitetaan alusta.

Nyt on pakko kyllä lopettaa. Tämä teksti vaikuttaa niin sekavalta, etten uskalla jatkaa enempää, ja alkaa muutenkin peti kutsua. Nähdään taas joskus.

No comments:

Post a Comment