Systembeskrivning Sakfrågan

Relevanta dokument
Sakfrågan Preliminär specifikation

Projektpresentation Sakfrågan

Labb LIVE. Exempelkod från föreläsningen. Plushögskolan Frågeutveckling inom MSSQL - SU14

Vyer, Prepared Statements, Triggers

Innehåll MySQL Intro. Allmänt om Lagrade Procedurer Enkel utformning Skapa en lagrad procedur Använda parameter som indata

SQLs delar. Idag. Att utplåna en databas. Skapa en databas

Databasens består av: Tabell Kolumner fält Rader poster (varje post är unik)

Du skall naturligtvis visa körexempel med output där det behövs i din rapport!

D1. Create Domain TEXT30 char(30) Default INGET VÄRDE! ;

Idag. Hur skapar vi och underhåller en databas? DD1370 (Föreläsning 4) Databasteknik och informationssystem 7,5 hp Hösten / 20

Sätta upp e-post server Ubuntu 14.04, del 1 installation av programvara, konfiguration av mysql och Postfix

Structured query language (SQL)

För att XCOPY i SQL Server Express ska fungera måste data och logg ligga i samma mapp, vilket naturligtvis inte är så bra.

Skapa exempeldatabasen

Design och underhåll av databaser

TENTAMEN DATABASKUNSKAP ITEK12

DDL Kommandon CREATE/DROP Database CREATE /ALTER/DROP Table ALTER/ADD/DROP Column CREATE /ALTER/DROP Index

VAD GÖR DU / VEM ÄR DU?

Lär känna MS SQL 2008 / Övning. Observera. Tips. Förberedelse

Klientprogrammering mot databaser

Nya webbservern Dvwebb.mah.se

Denna laboration skapades för elever vid Roslagens Högskola men kan användas av vem som helst. Namnen på servrarna måste i så fall ändras.

9. :new och :old -värden 10. Triggerns olika delar 11. Olika typer av triggrar 12. Kodexempel. Pär Douhan,

1. SQL DML (Data Manipulation Language) 2. Lägga till data. 4. Uppdatera data 5. Aktivera default value 6. Hantera datum 7.

Webbservrar, severskript & webbproduktion

Uppstart Inloggning SSMS Skapa Databas Skapa Tabell Skapa Diagram, Fk, RI Hantering av Index, Pk, Fk, Ix Constraints Beräknande fält Några funktioner

WCMS-15, Webbutvecklare CMS

VAD GÖR DU / VEM ÄR DU?

Övningar i SQL. SQLAccess.doc Ove Lundgren

TER3. Försättsblad till skriftlig tentamen vid Linköpings universitet G28 TEN1 Webprogrammering och databaser Tentamen IDA 1 (7)

Genomgång av tentamen. Databasteknik ITHS 4/3 2016

Översikt. Installation av EasyPHP 1. Ladda ner från Jag använder Release Installera EasyPHP.

Lektion 5 HTML, CSS, PHP och MySQL

Innehåll Programability Del 2

1.Lär känna MS SQL Observera. Tips. Förberedelse

Sync Master startas via Task Scedule (schemaläggaren). Programmet kan köras på servern utan att någon är inloggad på servern.

WWW. Exempel på klientsidan. Överföring av en html-fil. Snyggare variant. Verkligt format. Meddelandeformat för begäran HTTP

MySQL - testmiljöer på minuter. Thomas Johansson IT-avdelningen

1. PLSQL 2 2. Select into

Vid problem med programmet kontakta alltid C/W Cadware AB på telefon

Starta MySQL Query Browser

Dokumentation för VLDIT AB. Online classroom

1. SQL DDL (Data Definition Language) 2. Skapa tabell

Skapa din egen MediaWiki

Sample exam questions. Database exam TIG058

Databasföreläsning. Del 2 lagrade procedurer, vyer och transaktioner

Innehåll. MySQL Grundkurs

Lösningsförslag, tentamen i Databaser

Föreläsning 2: Översikt över ett databassystem

tclogin.com Service Desk Tillgång till TeleComputing TCAnyWare

INTRODUKTION TILL JDBC

3. Dynamiska webbplatser, 20 Yhp (4 v)

Manual för din hemsida

Introduktion Schenker-BTL AB, Stab IT Beskrivning över informationsintegreringmed Schenker, metodbeskrivning version 1.

732G16: Databaser - Design och programmering

Labb LABB 1. Databassagan och en rundtur i databasers märkliga värld. Plushögskolan Frågeutveckling inom MSSQL - SU14

Spara papper! Skriv inte ut sammanfattning utan ladda ner PDF!

Databaser - Design och programmering. Kursöversikt. Exempel: telefonbok. Varför databaser?

Installera din WordPress med 9 enkla steg

Introduktion MySQL och MariaDB

Disposition. 1. Kopplingen mellan Processanalys (DFDdiagram) 2. Treskikts Client-Server arkitektur (Fig 1.8) 3. Data layer

Administrationsmanual ImageBank 2

Startanvisning för Bornets Internet

Statistik från webbplatser

INSTALLATION...3 ATT KOMMA IGÅNG...3 PROGRAMMETS DESIGN...4 LÄGGA TILL TABELL...4 EDITERA TABELL...4 EDITERA RELATION...5 SPARA OCH AVSLUTA...

Biometria Violweb. Kom-igång-guide. Januari Sammanfattning Den här anvisningen är till för dig som ska börja använda dig av Biometrias tjänster.

Utkast/Version (8) Användarhandledning - inrapportering maskin-till-maskin

REGION SKÅNE VDI KLIENTINSTALLATION

Bokningslista Handledare

Ekonomiportalen Sa kommer du iga ng

Databaskunskap 7,5 högskolepoäng Provmoment: Ladokkod: Tentamen ges för:

Informa5onsmodellering

Databasutveckling Introduktion till SQL och TSQL

Systembeskrivning. Alhanko

Innehåll Security. Chapter 4 och 7 Beginning SQL Server 2008 for Developers

Instruktion för integration mot CAS

OBS! Figuren visar inte alla aspekter och objekt som är inblandade i säkerhetssystemet.

Tekis-FB Systemkrav

Quadri DCM Handledning för administratörer och användare i projekt som kör Quadri DCM. Version

! Teori och praktik. ! Ändringar från förra året. ! Examination (tenta, projekt) LiU. ! Varför ni? ! Varför överhuvudtaget? LiU

TEKNISK SPECIFIKATION. för TIDOMAT Portal version 1.7

FLEX Personalsystem. Uppdateringsanvisning

IT-körkort för språklärare. Modul 2: Blogg

ADO.NET Murach Kapitel 17-20

Biometria Violweb. Kom-igång-guide. Mars Sammanfattning Den här anvisningen är till för dig som ska börja använda dig av Biometrias tjänster.

Vad är molnet? Vad är NAV i molnet? Vem passar NAV i molnet för? Fördelar med NAV i molnet Kom igång snabbt...

Spara papper! Skriv inte ut sammanfattning utan ladda ner PDF!

KAP 18 SQL SERVER AGENT

Installation och konfiguration av klientprogramvara 2c8 Modeling Tool

1. Treskiktsarkitektur 2. Applika1onsprogramvara 3. Teknisk programvara. Kapitel 6 sid

Krav på säker autentisering över öppna nät

Bokningslista Examinator

Sync Master startas via Task Scedule (schemaläggaren). Programmet kan köras på servern utan att någon är inloggad på servern.

Övning MS SQL och MVC del 2

FNTSK SKNNK Fonetisk sökning

Labora&on 1 Introduk&on &ll utvecklingsmiljön övningar/uppgi<er

Lösenordsportalen Hosted by UNIT4 For instructions in English, see further down in this document

Transkript:

KTH Programutvecklingsprojekt, 2D1954 Nada - Institutionen för Numerisk analys och datalogi 2003-04-28 Systembeskrivning Sakfrågan Amr El-Ghazaly Joakim Andersson John Holmström Jens Modig Carl Drott

SYSTEMÖVERSIKT 3 BAKGRUND 3 KLIENT/SERVER-MODELLEN 3 SYSTEMETS STRUKTUR 4 DATABASEN 5 E-POSTSERVER 5 APPLIKATIONSSERVER/WEBBSERVER 5 KLIENTPROGRAMVARA 5 PROGRAMVARA 5 SIDORNAS/ANVÄNDARGRÄNSSNITTETS STRUKTUR 7 SERVLETKLASSERNA OCH DERAS HJÄLPKLASSER 11 PACKAGE ADMIN 11 PACKAGE BASE 11 PACKAGE UTILS 12 JSP-FILERNA 13 BASE 13 ADMIN 13 BILAGA 1 15 DATABASSTRUKTUR 15 BILAGA 2 16 DDL-KOMMANDON FÖR DATABASSTRUKTUREN 16 BILAGA 3 20 STORED PROCEDURES OCH TRIGGERS I DATABASEN 20 2

Systemöversikt Bakgrund Systembeskrivningen behandlar ett system som utvecklats på uppdrag av Oskar Rönnberg på Svenska Institutet för Tillämpad Beteendeanalys. Systemet vi har utvecklat ska presentera argument för och emot olika aktuella politiska sakfrågor. Systemet hanterar olika typer av användare med olika rättigheter. När vi valt plattform, programspråk och serverfunktioner så har vi konstant valt enligt dessa kriterier: de ska vara erkända, spridda, säkra och gratis. Vi har använt JSP/Servlets för att implementera webbgränssnittet och tillhörande funktioner med Tomcat som serversystem. För databasfunktionen har vi använt oss av PostgreSQL. Systemet är en trelagerslösning enligt klient/server princip. Klient/Server-modellen Modellen går ut på att en process eller ett program utnyttjar en tjänst som en annan process eller ett annat program tillhandahåller. Den process som efterfrågar tjänsten kallas då klient och den process som tillhandahåller tjänsten kallas server. Klient/server-modellen innebär stora fördelar i distribuerade system. Om klienten vill utnyttja en tjänst skickar den en förfrågan till servern. Klienten behöver inte veta var servern är fysiskt belägen utan det räcker med en adress till servern, denna förfrågan behandlas sedan av något annat program som skickar förfrågan vidare (jmf med posten). En annan fördel med modellen är att flera klienter kan dela en resurs, t ex. en skrivare. I vårat fall används en tunn klient i form av en webbläsare, det innebär att klienten bara används för presentera resultaten från servern, all logik och alla beräkningar sker på serversidan. 3

Systemets struktur Systemet är uppbyggt i en trelagersstruktur bestående av följande lager, lagringslagret, logiklagret och presentationslagret. Figur 1: Bild av systemets trelagerstruktur 4

Databasen Modulbeskrivning I databasen lagras informationen i olika tabeller. Den databas som används är Postgresql. Det fanns ett par anledningar till att vi valde Postgresql. För det första har medlemmarna i gruppen använt denna förut. Den är också gratis samt väldokumenterad på nätet. Den har kraftfulla funktioner som t ex. Triggers och Stored procedures. Vi valde att lägga en stor del av sqlfrågorna som Stored procedures i databasen som en applikation kan anropa utifrån. Triggers användes för att hålla databasen konsistent vid exempelvis uppdatering av betyg för inlägg. Kommunikationen med databasen sker via jdbc. För databasstruktur se bilaga 1. E-postserver Det behövs också tillgång till en mailserver som stödjer SMTP för att kunna skicka ut lösenorden till nyregistrerade användare. Ska installatören själv sätta upp en sådan rekommenderas ett *nix-system med qmail, som anses säkrare och bättre än det vanligaste alternativet sendmail. Applikationsserver/Webbserver Som applikations- och webbserver används Tomcat. Här körs våra program såsom Connection pool, servlets och jsp. Connection poolen håller ett antal uppkopplingar öppna mot databasen hela tiden och servletklasserna lånar en uppkoppling från poolen vid behov, när servletklassen sedan är klar med uppkopplingen lämnas den tillbaka till poolen. Servletklasserna sköter har hand om logiken i systemet och kommunicerar med jsp-sidor, javabeans och databas. Jsp-sidorna sköter presentationen av data från servletklasserna. Jsp-sidorna skickar också vidare användarinmatningar till servletklasserna. Klientprogramvara Klientprogramvaran är den programvara som användaren använder för att kommunicera med en serverapplikation som ligger på ett annat ställe lokalt eller i ett nätverk (t ex. Internet). För att kommunicera med vårat system används en webbläsare med stöd för javascript som finns förinstallerad i de flesta moderna operativsystem. Programvara Följande programvara ska installeras på server-sidan Postgresql 7.3.x E-postserver t ex. qmail Tomcat 4.x pg73jdbc3.jar, dvs jdbc 3.0 för postgresql 7.3.x JDK 1.4SE Våran programvara 5

Om systemet ska användas i en miljö med hög belastning kan man installera IBM's jikes, som erbjuder bättre prestanda än Suns javakompilator. Följande programvara behövs på klientsidan Webbläsare som klarar javascript och css 6

Sidornas/Användargränssnittets struktur Vi identifierade fyra olika aktörer. Dessa är besökare, registrerade användare, moderatorer samt administratörer. Alla aktörer har förutom sina specifika funktioner samma möjligheter som de lägre aktörerna har. Här presenteras de användargränssnitt som vi utgått från i jspdesignen. Besökare avser den stora massan som träffar på webbsidan. De tar del av sakfrågorna, röstar för eller emot dem och kan skriva inlägg. Figur 2: Sidstruktur för en anonym användare 7

En registrerad användare är en besökare som vill aktivt påverka vilka inlägg som ska visas för andra besökare. Figur 3: Sidstruktur för en inloggad registrerad användare 8

Moderatorer har ansvar för att stötande eller olämpliga inlägg tas bort. En moderator blir tilldelad en eller flera sakfrågor att moderera. Figur 4: Sidstruktur för en moderator 9

Administratörer hanterar användare och moderatorer och lägger till sakfrågor. Figur 5: Sidstruktur för en administratör 10

Servletklasserna och deras hjälpklasser (Se JavaDoc för ytterligare information om dess funktionalitet.) Package admin Funktioner för att administrera innehållet på webbsidan och dess användare, moderatorer och administratörer. Är endast tillgängliga för inloggade, behöriga användare. AddAdmin Servletklassen lägger till en administratörskoppling i databasen till en angiven användare. Används av addadmin.jsp. AddModerator Lägger till en moderatorkoppling till en specificerad användare. Används av addmoderator.jsp. ClearReports Låter en administratör eller en moderator nollställa anmälningsräknaren för ett inlägg så att detta inlägg inte längre finns med bland de inlägg som ska undersökas. PostTopic Används av en administratör för att skapa en ny sakfråga i systemet och databasen. RemoveUser Tar bort en användare ur databasen. Eventuella administratörs- eller moderatorkopplingar tas samtidigt bort, alla inläggsröster försvinner och berörda inlägg får sitt betygsvärde omräknat (via trigger i databasen). Reported Servletklassen tar bort ett inlägg så att det inte visas för besökare på sidan. Sparas i en separat tabell i databasen. ReturnPost Återställer ett tidigare borttaget inlägg. Flyttar tillbaka instansen till inläggstabellen i databasen så att det återigen syns på sidan. UserDisplay Databasbean som används av administratörs-jsp:er. Tillhandahåller att antal funktioner för att få vyer över bland annat användare som finns i systemet. Package base Utgör de standardfunktioner som används av flertalet användare. ChangePass Låter en användare byta ut sitt lösenord. 11

Create Lägger till informationen för en ny användare i systemet. Kontrollerar att en för systemet unik emailadress är angiven, tilldelar ett slumpgenererat lösenord och mailar ut informationen till den specificerade e-postadressen. (För att göra det svårare för en användare att registrera flera konton) Login Kontrollerar att det angivna lösenordet matchar e-postadressen och tar reda på användarens nivå i systemet samt initierar en session och knyter den information som behövs till denna. Post Skapar ett nytt inlägg i databasen, knutet till den önskade sidan i sakfrågan. PostVote Registrerar en röst i databasen för en användare förutsatt att ingen tidigare koppling finns. Report Anmäler ett inlägg så att det kan granskas av administratörer och behöriga moderatorer. Gör detta genom att öka på inläggets anmälningsräknare. TopicVote Registrerar en röst i en sakfråga och/eller hämtar aktuell ställning i omröstningen. Markerar också i en cookie att besökaren röstat i sakfrågan. Skulle det vara en registrerad användare så sparas också ställningstagandet i databasen så att användaren senare kan rösta på inläggen i sakfrågan. Package utils Hjälpklasser och Javabeans som kan användas av samtliga servlets. connectionpool.connectionpoolmanager Tillhandahåller databaskopplingar till servlets och hjälpklasser. Detta utförs med en ConnectionPool som håller ett antal databaskopplingar öppna som andra klasser kan låna. Display Den centrala hjälpklassen för alla jsp's som behöver hämta information ur databasen. Hanterar bland annat all visning av sakfrågor. Mailer En bean som upprättar kontakt med en specificerad SMTP-server och utför kommunikationen som behövs för att skicka e-post. Utilities Omfattande klass med statiska metoder för till exempel olika strängformatteringar, hantering av cookies, hämtning av parametrar, återkommande HTML-kod och maskering av länkar. VoteDisplay Används till röstningen på inlägg för registrerade användare. Hämtar de intressanta värdena ur databasen så de kan presenteras av de berörda jsp-filerna. 12

JSP-filerna Base Sajtens standardsidor som inte kräver rättigheter i systemet. index.jsp Utgör sajtens startsida changepass.jsp Tar in information från besökaren så att denna kan byta lösenord error.jsp Anropas när något fel uppstått som inte direkt kan hanteras. login.jsp Specifik sida för att logga in. När inloggning krävs för en aktion så omdirigeras användaren hit för att påvisa detta. Det finns annars en funktion för detta i menyn när en besökare inte är inloggad. logout.jsp Logga ut en användare, inaktiverar den pågående sessionen. post.jsp Tar in text, rubrik och signatur för ett inlägg och förmedlar det till databasen via Postservleten. revoteview.jsp Visar upp de inlägg man redan röstat på, om en användare vill ändra sin röst. viewtopic.jsp Visar upp en specifik sakfråga och de bästa inläggen för båda sidor. voteview.jsp Här ser man alla inlägg i en sakfråga som man inte har röstat på ännu och kan lägga sin röst på dem, varefter de hamnar i revoteview. Admin Alla funktioner som är begränsade till behöriga användare återfinns här. addadmin.jsp Här kan en administratör lägga till en ny administratör utifrån de befintliga användarna i databasen. addmoderator.jsp Låter en administratör koppla en användare eller en moderator med en sakfråga. adminview.jsp 13

Här kan en administratör se en förteckning över alla administratörer, ta bort dem och se den information som sparas i databasen. moderatorview.jsp Som ovan fast över alla moderatorer. userview.jsp Samma som ovan men alla vanliga användare. posttopic.jsp Tillåter en administratör att skapa en ny sakfråga och lägga till denna i databasen. removedposts.jsp Här kan administratörer och behöriga moderatorer se en lista över alla borttagna inlägg och om de så önskar återställa dem. reportedposts.jsp Administratörer och moderatorer kan här se alla anmälda inlägg för de sakfrågor som de har rätt att moderera. De kan rensa anmälningar eller ta bort inläggen från besökarnas sidor. 14

Bilaga 1 Databasstruktur Databasstruktur för sakfrågan 15

Bilaga 2 DDL-kommandon för databasstrukturen DROP DATABASE opinion; CREATE DATABASE opinion WITH ENCODING = 'ISO_8859_9'; CREATE TABLE SAKFRAGA (sakfragaid SERIAL, namn VARCHAR (128) NOT NULL, beskrivning VARCHAR (2048) NOT NULL, skapad TIMESTAMPTZ NOT NULL, antal_for INTEGER NOT NULL, antal_mot INTEGER NOT NULL, PRIMARY KEY (sakfragaid) ); CREATE TABLE ANVANDARE (anvandareid SERIAL, epost VARCHAR (128) NOT NULL, losen VARCHAR(128) NOT NULL, skapad TIMESTAMPTZ NOT NULL, senaste_login TIMESTAMPTZ NOT NULL, UNIQUE (epost), PRIMARY KEY (anvandareid) ); CREATE TABLE INLAGG (inlaggid SERIAL, titel VARCHAR(128) NOT NULL, text VARCHAR(2048) NOT NULL, signatur VARCHAR(128) NOT NULL, sida CHAR(1) NOT NULL, skapad TIMESTAMPTZ NOT NULL, antal_klagomal INTEGER NOT NULL, ip_nummer VARCHAR (128) NOT NULL, summa_roster FLOAT NOT NULL, antal_roster FLOAT NOT NULL, betyg FLOAT NOT NULL, sakfragaid_ref INTEGER NOT NULL, PRIMARY KEY (inlaggid), CONSTRAINT FK_SAKF_INLGG FOREIGN KEY (sakfragaid_ref) REFERENCES SAKFRAGA (sakfragaid) ON DELETE CASCADE ); CREATE TABLE REFUSERAT_INLAGG 16

(refuserat_inlaggid SERIAL, titel VARCHAR (128) NOT NULL, text VARCHAR (2048) NOT NULL, signatur VARCHAR (128) NOT NULL, sida CHAR (1) NOT NULL, skapad TIMESTAMPTZ NOT NULL, antal_klagomal INTEGER NOT NULL, ip_nummer VARCHAR (128) NOT NULL, summa_roster FLOAT NOT NULL, antal_roster FLOAT NOT NULL, betyg FLOAT NOT NULL, sakfragaid_ref INTEGER NOT NULL, PRIMARY KEY (refuserat_inlaggid), CONSTRAINT FK_SAKF_REFUS_INLGG FOREIGN KEY (sakfragaid_ref) REFERENCES SAKFRAGA (sakfragaid) ON DELETE CASCADE ); CREATE TABLE ADMINISTRATOR (administratorid SERIAL, namn VARCHAR (128) NOT NULL, anvandareid_ref INTEGER NOT NULL, PRIMARY KEY(administratorID), UNIQUE(anvandareID_REF), CONSTRAINT FK_ANV_ADMIN FOREIGN KEY (anvandareid_ref) REFERENCES ANVANDARE (anvandareid) ON DELETE CASCADE ); CREATE TABLE MODERATOR_SAKFRAGA (moderatorid SERIAL, namn VARCHAR (128) NOT NULL, sakfragaid_ref INTEGER NOT NULL, anvandareid_ref INTEGER NOT NULL, UNIQUE (sakfragaid_ref,anvandareid_ref), PRIMARY KEY(moderatorID), CONSTRAINT FK_SAKFRG_MOD FOREIGN KEY (sakfragaid_ref) REFERENCES SAKFRAGA (sakfragaid) ON DELETE CASCADE, CONSTRAINT FK_ANV_MOD FOREIGN KEY (anvandareid_ref) REFERENCES ANVANDARE (anvandareid) ON DELETE CASCADE 17

); CREATE TABLE STANDPUNKT (standpunktid SERIAL, standpunkt CHAR(1) NOT NULL, anvandareid_ref INTEGER NOT NULL, sakfragaid_ref INTEGER NOT NULL, PRIMARY KEY (standpunktid), UNIQUE(anvandareid_ref,sakfragaid_ref), CONSTRAINT FK_ANV_STAP FOREIGN KEY (anvandareid_ref) REFERENCES ANVANDARE (anvandareid) ON DELETE CASCADE, CONSTRAINT FK_SAKFR_STAP FOREIGN KEY (sakfragaid_ref) REFERENCES SAKFRAGA (sakfragaid) ON DELETE CASCADE ); CREATE TABLE BETYG (betygid SERIAL, varde INTEGER NOT NULL, inlaggid_ref INTEGER NOT NULL, anvandareid_ref INTEGER NOT NULL, UNIQUE(inlaggid_ref,anvandareid_ref), PRIMARY KEY (betygid), CONSTRAINT FK_INLGG_BETG FOREIGN KEY (inlaggid_ref) REFERENCES INLAGG (inlaggid) ON DELETE CASCADE, CONSTRAINT FK_ANVND_BETG FOREIGN KEY (anvandareid_ref) REFERENCES ANVANDARE (anvandareid) ON DELETE CASCADE ); DROP VIEW JA_INLAGG; CREATE VIEW JA_INLAGG AS SELECT * FROM INLAGG WHERE sida = 'y' ORDER BY betyg DESC; DROP VIEW NEJ_INLAGG; CREATE VIEW NEJ_INLAGG AS SELECT * FROM INLAGG WHERE sida = 'n' ORDER BY betyg DESC; 18

DROP VIEW GET_USER; CREATE VIEW GET_USER AS SELECT * FROM ANVANDARE WHERE anvandareid NOT IN ((SELECT anvandareid_ref FROM administrator) UNION (SELECT anvandareid_ref FROM moderator_sakfraga)); DROP VIEW GET_MODERATOR; CREATE VIEW GET_MODERATOR AS SELECT moderatorid, namn, sakfragaid_ref, anvandare.* FROM moderator_sakfraga, anvandare WHERE anvandareid_ref=anvandareid; DROP VIEW GET_ADMINISTRATOR; CREATE VIEW GET_ADMINISTRATOR AS SELECT administratorid, namn, anvandare.* FROM administrator, anvandare WHERE anvandareid_ref=anvandareid; 19

Bilaga 3 Stored procedures och Triggers i databasen DROP FUNCTION insert_user(text,text); CREATE FUNCTION insert_user(text, text) RETURNS int AS' ep ALIAS FOR $1; pwd ALIAS FOR $2; anvid INT; INSERT INTO anvandare (epost, losen, skapad, senaste_login) VALUES (ep, pwd, ''now'', ''now''); anvid := currval(''anvandare_anvandareid_seq''); return anvid; DROP FUNCTION get_users(); CREATE FUNCTION get_users() RETURNS REFCURSOR AS' marker CURSOR FOR select * from anvandare; OPEN marker; return marker; DROP FUNCTION get_ja_posts(int,int); DROP FUNCTION get_ja_posts(int,int,int); CREATE FUNCTION get_ja_posts(int,int,int) RETURNS REFCURSOR AS' ja_postmarker CURSOR (key int,os int) FOR select * from JA_INLAGG WHERE sakfragaid_ref=$2 limit key OFFSET os; OPEN ja_postmarker($1,$3); return ja_postmarker; DROP FUNCTION get_nej_posts(int,int); DROP FUNCTION get_nej_posts(int,int,int); CREATE FUNCTION get_nej_posts(int,int,int) RETURNS REFCURSOR AS' nej_postmarker CURSOR (key int,os int) FOR select * from NEJ_INLAGG WHERE sakfragaid_ref=$2 limit key OFFSET os; OPEN nej_postmarker($1,$3); 20

return nej_postmarker; DROP FUNCTION get_topics(); CREATE FUNCTION get_topics() RETURNS REFCURSOR AS' topicmarker CURSOR FOR SELECT * FROM SAKFRAGA ORDER BY skapad DESC; OPEN topicmarker; return topicmarker; DROP FUNCTION kind_of_user(int); CREATE FUNCTION kind_of_user(int) RETURNS int AS' user_rec RECORD; admin_rec RECORD; mod_rec RECORD; id ALIAS FOR $1; SELECT INTO user_rec anvandareid FROM get_user WHERE anvandareid=id; UPDATE anvandare SET senaste_login=''now'' WHERE anvandareid=id; IF user_rec.anvandareid IS NOT NULL THEN RETURN 0; END IF; SELECT INTO admin_rec anvandareid_ref FROM administrator WHERE anvandareid_ref=id; IF admin_rec.anvandareid_ref IS NOT NULL THEN RETURN 1; END IF; SELECT INTO mod_rec anvandareid_ref FROM moderator_sakfraga WHERE anvandareid_ref=id; IF mod_rec.anvandareid_ref IS NOT NULL THEN RETURN 2; END IF; COMMIT; return -1; 21

DROP FUNCTION post(text,text,text,char,text,int); CREATE FUNCTION post(text,text,text,char,text,int) RETURNS int AS' the_titel ALIAS FOR $1; the_text ALIAS FOR $2; the_signatur ALIAS FOR $3; the_sida ALIAS FOR $4; the_ipnum ALIAS FOR $5; the_sakfragaid ALIAS FOR $6; post_id int; INSERT INTO inlagg (titel, text, signatur, sida,skapad,antal_klagomal,ip_nummer, summa_roster,antal_roster,betyg,sakfragaid_ref) VALUES (the_titel,the_text,the_signatur,the_sida,''now'',0,the_ipnum, 0,0,0,the_sakfragaid); post_id := currval(''inlagg_inlaggid_seq''); return post_id; DROP FUNCTION NEXT_TOPIC(int); CREATE FUNCTION NEXT_TOPIC(int) RETURNS REFCURSOR AS' current_topic ALIAS FOR $1; next_markor CURSOR FOR SELECT sakfragaid,namn FROM sakfraga WHERE sakfragaid > current_topic ORDER BY sakfragaid LIMIT 1; OPEN next_markor; RETURN next_markor; DROP FUNCTION PREV_TOPIC(int); CREATE FUNCTION PREV_TOPIC(int) RETURNS REFCURSOR AS' current_topic ALIAS FOR $1; prev_markor CURSOR FOR SELECT sakfragaid,namn FROM sakfraga WHERE sakfragaid < current_topic ORDER BY sakfragaid; OPEN prev_markor; RETURN prev_markor; 22

DROP FUNCTION GET_TOPIC(int); CREATE FUNCTION GET_TOPIC(int) RETURNS REFCURSOR AS' topic_id ALIAS FOR $1; topic_marker CURSOR FOR SELECT * FROM sakfraga WHERE sakfragaid=topic_id; OPEN topic_marker; RETURN topic_marker; DROP FUNCTION post_topic(text,text); CREATE FUNCTION post_topic(text,text) RETURNS int AS' the_namn ALIAS FOR $1; the_beskrivning ALIAS FOR $2; topic_id int; INSERT INTO sakfraga (namn, beskrivning, skapad, antal_for, antal_mot) VALUES (the_namn, the_beskrivning, ''now'', 0, 0); topic_id := currval(''sakfraga_sakfragaid_seq''); return topic_id; DROP FUNCTION topic_vote(int,char); CREATE FUNCTION topic_vote(int,char) RETURNS REFCURSOR AS' topic_id ALIAS FOR $1; vote ALIAS FOR $2; topic_vote_marker CURSOR FOR SELECT antal_for,antal_mot FROM sakfraga WHERE sakfragaid=topic_id; IF vote = ''y'' THEN UPDATE sakfraga SET antal_for = (antal_for+1) WHERE sakfragaid = topic_id; END IF; IF vote = ''n'' THEN 23

UPDATE sakfraga SET antal_mot = (antal_mot+1) WHERE sakfragaid = topic_id; END IF; OPEN topic_vote_marker; RETURN topic_vote_marker; DROP FUNCTION GET_NO_OF_UNVOTED(int,int); CREATE FUNCTION GET_NO_OF_UNVOTED(int,int) RETURNS int AS' topic_id ALIAS FOR $1; user_id ALIAS FOR $2; number int; side char; SELECT INTO side standpunkt.standpunkt FROM standpunkt WHERE anvandareid_ref=user_id AND sakfragaid_ref=topic_id; SELECT INTO number count(inlaggid) FROM inlagg WHERE sakfragaid_ref=topic_id AND sida=side AND inlaggid NOT IN (SELECT inlaggid from inlagg,betyg WHERE sakfragaid_ref=topic_id AND inlaggid_ref=inlaggid AND anvandareid_ref = user_id); return number; DROP FUNCTION GET_NO_OF_VOTED(int,int); CREATE FUNCTION GET_NO_OF_VOTED(int,int) RETURNS int AS' topic_id ALIAS FOR $1; user_id ALIAS FOR $2; number int; side char; SELECT INTO side standpunkt.standpunkt FROM standpunkt WHERE anvandareid_ref=user_id AND sakfragaid_ref=topic_id; SELECT INTO number count(inlaggid) FROM inlagg WHERE sakfragaid_ref=topic_id AND sida=side AND inlaggid IN (SELECT inlaggid from inlagg,betyg WHERE sakfragaid_ref=topic_id AND inlaggid_ref=inlaggid AND anvandareid_ref = user_id); return number; DROP FUNCTION VOTE_VIEW(int,int); DROP FUNCTION VOTE_VIEW(int,int,int,int); CREATE FUNCTION VOTE_VIEW(int,int,int,int) RETURNS REFCURSOR AS' 24

topic_id ALIAS FOR $1; user_id ALIAS FOR $2; no_of_posts ALIAS FOR $3; the_offset ALIAS FOR $4; side char; vote_view_marker CURSOR (key char) FOR SELECT DISTINCT(inlagg.*) FROM inlagg WHERE sakfragaid_ref=topic_id AND sida=key AND inlaggid NOT IN (SELECT inlaggid from inlagg,betyg WHERE sakfragaid_ref=topic_id AND inlaggid_ref=inlaggid AND anvandareid_ref = user_id) ORDER BY betyg DESC LIMIT no_of_posts OFFSET the_offset; SELECT INTO side standpunkt.standpunkt FROM standpunkt WHERE anvandareid_ref=user_id AND sakfragaid_ref=topic_id; IF NOT FOUND THEN RAISE EXCEPTION ''ERROR: EJ VALT SIDA''; END IF; OPEN vote_view_marker(side); RETURN vote_view_marker; DROP FUNCTION RE_VOTE_VIEW(int,int); DROP FUNCTION RE_VOTE_VIEW(int,int,int,int); CREATE FUNCTION RE_VOTE_VIEW(int,int,int,int) RETURNS REFCURSOR AS' topic_id ALIAS FOR $1; user_id ALIAS FOR $2; no_of_posts ALIAS FOR $3; the_offset ALIAS FOR $4; side char; vote_view_marker CURSOR (key char) FOR SELECT DISTINCT(inlagg.*) FROM inlagg WHERE sakfragaid_ref=topic_id AND sida=key AND inlaggid IN (SELECT inlaggid from inlagg,betyg WHERE sakfragaid_ref=topic_id AND inlaggid_ref=inlaggid AND anvandareid_ref = user_id) ORDER BY betyg DESC LIMIT no_of_posts OFFSET the_offset; SELECT INTO side standpunkt.standpunkt FROM standpunkt WHERE anvandareid_ref=user_id AND sakfragaid_ref=topic_id; IF NOT FOUND THEN RAISE EXCEPTION ''ERROR: EJ VALT SIDA''; END IF; OPEN vote_view_marker(side); 25

RETURN vote_view_marker; DROP FUNCTION POST_VOTE(int,int,int); CREATE FUNCTION POST_VOTE(int,int,int) RETURNS int AS' value ALIAS FOR $1; post_id ALIAS FOR $2; user_id ALIAS FOR $3; INSERT INTO betyg (varde,inlaggid_ref,anvandareid_ref) VALUES (value,post_id,user_id); RETURN 1; DROP FUNCTION calculate_betyg() CASCADE; CREATE FUNCTION calculate_betyg() RETURNS OPAQUE AS' UPDATE inlagg SET antal_roster=antal_roster+1, summa_roster=summa_roster+new.varde, betyg=(summa_roster+new.varde)/(antal_roster+1) WHERE inlaggid=new.inlaggid_ref; RETURN NEW; DROP TRIGGER calculate_betyg_trigger ON betyg; CREATE TRIGGER calculate_betyg_trigger AFTER INSERT ON betyg FOR EACH ROW EXECUTE PROCEDURE calculate_betyg(); DROP FUNCTION MOVE_POST_TO_REF(int); CREATE FUNCTION MOVE_POST_TO_REF(INT) RETURNS int AS' post_id ALIAS FOR $1; data RECORD; SELECT INTO data * FROM inlagg WHERE inlaggid=post_id; IF NOT FOUND THEN RAISE EXCEPTION ''ERROR: Inlägg finns inte''; END IF; INSERT INTO refuserat_inlagg (titel, text, signatur,sida, skapad, antal_klagomal,ip_nummer,summa_roster,antal_roster,betyg,sakfragaid_ref) VALUES (data.titel, data.text, data.signatur,data.sida, data.skapad, 26

data.antal_klagomal,data.ip_nummer,data.summa_roster, data.antal_roster,data.betyg,data.sakfragaid_ref); DELETE FROM inlagg WHERE inlaggid=post_id; RETURN 0; DROP FUNCTION MOVE_REF_TO_POST(int); CREATE FUNCTION MOVE_REF_TO_POST(INT) RETURNS int AS' ref_id ALIAS FOR $1; data RECORD; SELECT INTO data * FROM refuserat_inlagg WHERE refuserat_inlaggid=ref_id; IF NOT FOUND THEN RAISE EXCEPTION ''ERROR: Refuserat inlagg existerar inte''; END IF; INSERT INTO inlagg (titel, text, signatur,sida, skapad, antal_klagomal,ip_nummer,summa_roster,antal_roster,betyg,sakfragaid_ref) VALUES (data.titel, data.text, data.signatur,data.sida, data.skapad, data.antal_klagomal,data.ip_nummer,data.summa_roster, data.antal_roster,data.betyg,data.sakfragaid_ref); DELETE FROM refuserat_inlagg WHERE refuserat_inlaggid=ref_id; RETURN 0; DROP FUNCTION remove_betyg() CASCADE; CREATE FUNCTION remove_betyg() RETURNS OPAQUE AS' DELETE FROM BETYG WHERE betyg.anvandareid_ref=new.anvandareid_ref AND betyg.inlaggid_ref=inlagg.inlaggid AND inlagg.sakfragaid_ref=new.sakfragaid_ref; RETURN NEW; DROP TRIGGER remove_betyg_trigger ON standpunkt; CREATE TRIGGER remove_betyg_trigger BEFORE UPDATE ON standpunkt FOR EACH ROW EXECUTE PROCEDURE remove_betyg(); DROP FUNCTION update_betyg() CASCADE; CREATE FUNCTION update_betyg() RETURNS OPAQUE AS' 27

the_antal int; SELECT INTO the_antal antal_roster FROM inlagg WHERE inlaggid = OLD.inlaggid_ref; IF the_antal = 1 THEN UPDATE inlagg SET antal_roster=0, summa_roster=0, betyg=0 WHERE inlaggid=old.inlaggid_ref; END IF; IF the_antal > 1 THEN UPDATE inlagg SET antal_roster=antal_roster-1, summa_roster=summa_roster-old.varde, betyg=(summa_roster-old.varde)/(antal_roster-1) WHERE inlaggid=old.inlaggid_ref; END IF; RETURN OLD; DROP TRIGGER update_betyg_trigger ON betyg; CREATE TRIGGER update_betyg_trigger BEFORE DELETE ON betyg FOR EACH ROW EXECUTE PROCEDURE update_betyg(); 28