3. Osajärjestelmäkuvaus, tietokanta-orja **************************************** Tietokanta-orja on TaHKo:n osajärjestelmä, joka huolehtii tietokannan käsittelystä. Tähän kuuluu tedon haku, jossain määrin sen talletus, sekä käyttäjien autentikointi. Osajärjestelmä sisältää kirjastoluokan DBSlave ja DBResult-luokan, jota käytetään palauttaessa tietokantahakujen tuloksia. Virhetilanteissa tuotetaan DBException tai jokin sen alaluokista. A. Kaaviokuva ulkoisista ja sisäisistä olioista =============================================== [Tähän se kuva] DBSlave-luokka on yhteydessä tietokantaan ja tarjoaa tietokantapalveluja muille TaHKo:n osajärjestelmille. DBResult-luokka toimii tietovarastona hakutuloksia palautettaessa. Silä voi kysellä tiedot yksitellen tai pyytä ne XML-muodossa. B. Rajapinnan kuvaus toisiin osajärjestelmiin ============================================= Muut osajärjestelmät käyttävät tietokanta-osajärjestelmää DBSlave-luokan julkisten metodien avulla. DBSlave palauttaa tuloksensa joko XML-muodossa (Stringinä) tai DBResult-oliona, jolloin sen sisältämiin tietoihin pääsee käsiksi DBResult-luokan julkisilla metodeilla. [Linkit DBSalve:n & DBResult:in javadocciin] C. Rajapinnan kuvaus ulkoisiin elementteihin ============================================ Tietokannan käsittelyyn käytetään JDBC-rajapintaa. D. DBSlave:n luokkakuvaus ========================= D1. Tietosuunnitelma -------------------- DBSlaven sisältämät tiedot: dbURL : Tietokannan URL username : Tietokannan käyttäjätunnus password : Tietokannan salasana tahkoDB : TaHKo-tietokannan nimi DBResultin sisältämät tiedot: tableName : Taulun nimi, josta hakutulokset ovat peräisin columnCount : Tuloksen sarakkeiden määrä rowCount : Tuloksen rivien määrä columns : Joukko vektoreita, jotka sisältävät tuloksen tiedot sarakkeittain columnNames : Sarakkeiden nimet columnTable : Hajautustaulu, joka liittää sarakkeen nimet ja niiden tiedot sisältävät vektorit. D2. Toimintosuunnitelma ----------------------- Tietokannan käsittely tapahtuu kutsumalla luokan DBSlave metodeja. Vapaamuotoisia hakuja suorittava getFromDatabase-metodi palauttaa haun tulokset DBResult-oliona, jolta tiedot voidaan kysellä stringeinä, kokonaislukuina, doubleina tai objekteina tai koko tulos voidaan muuntaa XML-muotoon. D2.1 class DBSlave: ------------------- DBSlave on staattinen kirjastoluokka. Ennenkuin tietokantatoimintoja voidaan käyttää, luokka täytyy alustaa kutsumalla metodia setDBServer, joka asettaa tarvittavat parameterit yhteyden saamiseksi tietokantaan. Metodit: -------- public static void setDBServer(String driver, String protocol, String server, int port, String user, String passwd, String tahkoDB) Rekisteröi JDBC-ajuri Rakenna dbURL ("jdbc:" + protocol + "://" + server + ":" + port + "/") Aseta luokka muuttujien userName, password ja tahkoDB arvot public static boolean isDBServerSet() -Jos dbURL == null palauta false, muutoin true private static Connection getConnection(String db) -return DriverManager.getConnection(dbURL + db, username, password) public static DBResult getFromDatabase(String db, String table, Vector columns, String conditions, String orderingColumn, int orderingDir) -Rakenna SQL-kysely: *SELECT: Jos columns == null, tulee SELECT osaan "*" (kaikki sarakkeet), Muutoin kaikki columns-vektorin sisältävät sarakkeennimet pilkuilla eroteltuina *FROM: Annettu taulun nimi table *WHERE: Jos conditions-parameteri ei ole null, lisää WHERE-osa annetuilla ehdoilla. *ORDER BY: Mikäli orderingColumn-parameteri on annettu, lisää ORDER BY-osa annetulla sarakkeen nimellä ja suunnalla "ASC" tai "DESC" riippuen parametrista orderingDir. -Hae tietokantayhteys kutsulla getConnection(db) -Suorita kysely -Luo kyselyn tuloksesta DBResult-olio ja palauta se public static String getPageLogic(String name) -Hae logicxml-taulusta sarake address riviltä, jossa nimi täsmää annettuun käyttäen getFromDatabase-metodia. -Jos täsmäävä rivi löytyi, hae address-merkkijonon osoittamasta URLista löytyvä XML metodilla getStringFromURL ja palautta se public static String getLogicXSL(String name) -Hae logicxsl-taulusta sarake address riviltä, jossa nimi täsmää annettuun käyttäen getFromDatabase-metodia. -Jos täsmäävä rivi löytyi, hae address-merkkijonon osoittamasta URLista löytyvä XSL metodilla getStringFromURL ja palautta se private static String getStringFromURL(String urlStr) -Luo java.net.URL-instanssi annetulla merkkijonolla -Avaa URL:in InputStream -Luo InputStreamin sisältö ja palauta se merkkijonona public static String login(String name, String password) -Hae login-taulusta kaikki sarakkeet riviltä, jossa nimi ja salasana täsmäävät annettuihin käyttäen getFromDatabase- metodia. -Mikäli tulos on tyhjä, tuota InvalidLoginException, muutoin palauta tulos XML:änä (käyttäen metodia DBResult.toXML()) public static String loadOffer(int offerId) -Hae offer-taulusta sarake offer_xml annettuun ID:hen täsmäävältä riviltä käyttäen getFromDatabase-metodia. -Jos rivi löydettiin, palauta sarakkeen offer_xml sisältö public static void saveOffer(String offerXML) -Selvitä annetusta XML:stä myyjän ja asiakkaan tunnukset metodilla getSellerAndCustomerIds -Hae tietokantayhteys TaHKo-tietokantaan (getConnection) -Aseta myyjän ja asiakkaan tunnukset, tämänhetkinen aika ja offerXML uudelle riville tietokantaan public static void updateOffer(int id, String offerXML) -Selvitä annetusta XML:stä myyjän ja asiakkaan tunnukset metodilla getSellerAndCustomerIds -Päivitä parametrina annetun ID:n osoittamalle riville myyjän ja asiakkaan tunnukset, tämänhetkinen aika ja offerXML private static String[] getSellerAndCustomerIds(String xml) -Luo kaksi-alkioinen String taulukko ids. -Muodosta XML:stä DOM dokumentti -Hae dokumentista tagin 'seller_id' sisältö ja aseta se ids-taulukon ensimmäiseksi alkioksi. -Hae dokumentista tagin 'customer_id' sisältö ja aseta se ids-taulukon toiseksi alkioksi. -Palauta ids-taulukko D2.2 DBResult: -------------- Metodit: -------- public DBResult(ResultSet rs, String tableName) [konstruktori] -Aseta instanssin muuttuja tableName -Hae ResultSetMetaData ja aseta instanssin muuttuja columnCount metadatasta saatavan sarakkeiden määrän mukaan -Lue sarakkeiden nimet columnNames-taulukkoon, luo jokaiselle sarakkeelle vektori (columns-taulukko) ja aseta se columnTable-hajautustauluun sarakkeen nimellä -Käy läpi kaikki ResultSet:in rivit ja luo niiden sarakkeet columns-vektoreihin. Laske rivien määrä muuttujaan rowCount. public int getRowCount() -Palauta rowCount public int getColumnCount() -Palauta columnCount public Object getObject(String columnName, int row) public String getString(String columnName, int row) public int getInt(String columnName, int row) public double getDouble(String columnName, int row) -Etsi oikea sarake-vektori columnTable hajautustaulusta annetun sarakkeen nimen perusteella -Mikäli sarake löytyi, ja parametri row on välillä [0 - rowCount), palauta sieltä löytyvä arvo haluttuna tietotyyppinä. Mikäli tietotyyppi on väärä, tuota InvalidValueTypeException. public Object getObject(int column, int row) public String getString(int column, int row) public int getInt(int column, int row) public double getDouble(int column, int row) -Etsi sarakkevektorista column alkio row, mikäli parametrit column ja row ovat laillisissa rajoissa -Palauta löydetty arvo haluttuna tietotyyppinä. Mikäli tietotyyppi on väärä, tuota InvalidValueTypeException. public String toXML() -Aloita XML:n tuottaminen -tagilla, jossa parametrina 'table' taulun nimi. -Jos rivejä on lisää -tagi ja käy läpi kaikki rivit r: *lisää XML:ään -tagi *Käy läpi kaikki sarakkeet s: +Lisää XML:ään -tagi, jossa parametrina 'name'-sarakkeen nimi +lisää XML:ään sarakkeelta s ja riviltä r löytyvä arvo nerkkijonona tai +tyhjä merkkijono mikäli se on null. +Lisää XML:ään tagi. *Lisää XML:ään -tagi. Lisää -tagi. Jos rivejä ei ole, lisää -tagi -Lisää lopuksi XML:ään -tagi -Palauta XML