Wiki on Wheels -Wikipedia on your personal SQL server
Door Anton Kirschhock
Inhoudsopgave 1 Wiki on Wheels ..................................................................................................................................... 3 1.1 Dit document ................................................................................................................................. 3 1.2 De analyse van de Api.................................................................................................................... 3 2 De code (C#) ......................................................................................................................................... 3 2.1 C# ................................................................................................................................................... 3 2.2 De workflow .................................................................................................................................. 4 2.3 Configuratie bestand ..................................................................................................................... 4 2.4 Statistieken .................................................................................................................................... 4 3 Databank .............................................................................................................................................. 4 3.1 Het databank gebeuren................................................................................................................. 4 3.2 Het schema .................................................................................................................................... 5 3.3 De functies in de databank ............................................................................................................ 5 3.4 Configuratie ................................................................................................................................... 5 4 Testen ................................................................................................................................................... 5 4.1 Uitgevoerde testen ........................................................................................................................ 5 4.2 Ubuntu testen ............................................................................................................................... 5 Bijlagen .................................................................................................................................................... 6 Bijlage 1: Wiki van het project............................................................................................................. 6 Bijlage 2: echte Wikipedia schema .................................................................................................... 10 Bijlage 3: Wiki-on-Wheels Schema .................................................................................................... 11
2
Wiki on Wheels
Anton Kirschhock
1 Wiki on Wheels 1.1 Dit document Wiki on Wheels is een project door Anton Kirschhock. De opdracht bestond er in om Wikipedia (wat het MediaWiki software pakket gebruikt) te downloaden. In dit document wordt er beschreven hoe te het project evalueerde en bijkomende uitleg over hoe de code gedocumenteerd wordt. Ook zal in dit document de wiki die orgineel op Bitbucket stond (Bijlage 1), volledig ter beschikking gesteld worden.
1.2 De analyse van de Api De API van MediaWiki bestaat er in om bijna alles op te vragen van wat in de databank te vinden is. De tabellen die wikipedia gebruikt (zie afb. 1) is redelijk groot en complex. Ook worden niet alle relaties duidelijk getoond op databank niveau maar zijn de relaties deels op codeniveau in het software pakket. De namen die de databank ook gebruikt zijn niet altijd correct. Een voorbeeld hiervan is het entiteit Revision. Een revision moet niet noodzakelijk een revision van een pagina zijn maar kan ook een foto of een ander document zijn. Ook heeft een category niet alleen pagina’s maar ook afbeeldingen en andere bijkomende bestanden.
Na langdurige analyse van hoe men de afb. 1 Het relationeel schema van Wikipedia. Bijlage 2 geeft een duidelijkere weergave hiervan API kan aanpreken heeft men ontdekt dat er een LINQ-to-Wiki bestaat. LINQ (Language Integrated Query) is een manier binnen het .Net framework om over een enumerable te filteren en bepaalde elementen van de enumerable te extraheren. LINQ-to-Wiki zal intern de API van wikipedia aanpreken en het hierdoor makkelijker maken voor de ontwikkelaar om gegevens op te vragen.
2 De code (C#) 2.1 C# In dit stuk wordt de code-behind uitgelegd hoe de workflow in elkaar zit en bijkomende informatie over de code. Een API uitleg is te vinden onder http://kirschhock.com:8080/deployment/wikionwheels/documentation/
3
Wiki on Wheels
Anton Kirschhock
2.2 De workflow De workflow van de C# code is redelijk eenvoudig. Om de download onder te verdelen heeft men dit verdeeld in stappen. Stap 1 bestaat eruit om alle categories te downloaden. Hier worden alle categories gedownload afzonderlijk van elkaar en van de pages die gelinkt zijn hieraan. Stap 2 zal dan door alle categories itereren (op SQL niveau) en dan alle pagina’s opvragen die aan die categorie gelinkt zijn. Deze zal via een SQL functie in de databank toegevoegd worden indien de pagina ID niet gevonden is, gevolgd door het linken in de tussentabel tussen de categories en pages. Indien deze al bestaat wordt het toevoegen overgeslagen en zal de tussen tabel direct aangevuld worden. Nadat de pagina (ID en titel) is toegevoegd, zal voor alle revisions van die page opgevraagd worden. Na het toevoegen van alle revisions, zal de huidige revision gelinkt worden vanuit de page. De laatste stap (stap einde) bestaat er in om het HTML raport te genereren en het downloaden af te ronden.
2.3 Configuratie bestand Het programma gebruikt een configuratie bestand om het aanpasbaar te maken. Doormiddel van een key-value pair kan men een aanpassing maken. In het Wiki deel (bijlage 1) wordt er uitgelegd hoe dit werkt.
2.4 Statistieken Om te zien hoelang de code nodig heeft om x-aantal SQL statements uit te voeren, heeft men een raportgenerator toegevoegd aan de code-behind. Telkens als een stap begint, zal de begin tijd bijgehouden worden. Bij uitvoeringen van de SQL code zal ook het aantal statements voor die stap verhoogd worden. Op het einde zal een grafiek gemaakt worden (met behulp van de “System.Windows.Forms.DataVisualization.Charting” namespace) van de tijd per stap en het aantal SQL uitvoeringen en worden deze toegevoegd aan het raport. Het raport kan men vinden onder de map waar de executable is.
3 Databank 3.1 Het databank gebeuren In dit onderdeel wordt uitgelegd hoe het schema eruit ziet, uitleg over de functies en de configuratie hiervan.
4
Wiki on Wheels
Anton Kirschhock
3.2 Het schema Het schema is opgebouwd aanhand van wat downloadbaar is vanuit de API. Er is meer downloadbaar technisch gezien maar bij andere delen van wikipedia bestaat er vaak een kans dat de waarde private zijn (gebruiker namen).
3.3 De functies in de databank De databank heeft een aantal SQL (postgres) functies om het toevoegen makkelijker te maken. Deze functies zorgen er voor dat er geen duplicaten voorkomen, maar wel indien nodig een link tussen de pagina en de categories of revisions gemaakt wordt. Ook is dit handig om het werkt van de C# te delegeren naar de databank zelf.
afb. 2 Het schema van de databank. Het schema is duidelijker te zien in bijlage 3
3.4 Configuratie Ook hier kan men in het configuratie bestand gebruiken om de databank link mee te geven aan het C# programma. Deze informatie zijn host van de databank, port, databank/schema naam, username en password. Dit wordt meer uitgelegd in het wiki gedeelde over de databank.
4 Testen 4.1 Uitgevoerde testen Het programma werd getest met behulp van de Wikipedia in Fiji Hindi (http://hif.wikipedia.org/) . Gemiddeld duurde deze uitvoering van deze versie 6 uur. Later werd de Nederlandse Wikipedia getest om het programma te testen op grotere scala. Om de Nederlandse Wikipedia te downloaden, heeft het 4 dagen nodig gehad.
4.2 Ubuntu testen Om op een niet Microsoft platform Wiki On Wheels te gebruiken moet men op het platform volgende afhankelijkheden hebben: -
Laatste Mono versie (Ubuntu: sudo apt-get install mono-complete)
Om dat de applicatie uit te voeren ga naar de locatie waar het project is in de console en navigeer verder met : ‘cd WikiOnWheelsMono/bin/Debug’. Hierna voer het volgende commando uit: ‘mono WikiOnWheels.exe’
5
Wiki on Wheels
Anton Kirschhock
Bijlagen Bijlage 1: Wiki van het project
Database In this section I’ll explain how the backend works.
Powered by PostgreSQL The code which retrieves all the information is written with the OO Open-closed Principe, which ensures adaptable code. Standard is PostgreSQL implemented and used. To add a new Datasource, simply implement the interface IWikiOnWheelsDb and add the functionality required to the methods the interface asks you to use. To use the correct database you simply alter the Factory return statement for the DbOps from PostgreSQL to your own created class. private static IWikiOnWheelsDb DbOps { get { if (_sql == null) _sql = new PostgreSQL(); return _sql; } }
How to install the database This section will explain you how to get started step by step and how to configure the database. Depending on what database you want to use this can vary. This section will explain you for the PostgreSQL database only. 1) Install PostgreSQL. Make sure that the data location is big enough to hold a Wiki! (In the development I've used PostgreSQL Portable to hold the huge amount of data) 2) Create an user which can create a scheme 3) Execute the following SQL code to create the scheme (replace USERNAMEHERE with the username you have just created): CREATE SCHEMA wikionwheels AUTHORIZATION "USERNAMEHERE"; 4) Now execute the create table statements to create the relations set SEARCH_PATH to wikionwheels; CREATE TABLE categories( catid serial not null, cattitel VARCHAR(255), CONSTRAINT pk_cat PRIMARY KEY (catid) ); CREATE TABLE pages( pageid serial not null, currentrev int, CONSTRAINT pk_pages PRIMARY KEY (pageid) ); CREATE TABLE cathaspages( catid int, pageid int,
6
Wiki on Wheels
Anton Kirschhock
CONSTRAINT fk_cat_chp FOREIGN KEY (catid) REFERENCES categories ON UPDATE CASCADE ON DELETE CASCADE, CONSTRAINT fk_page_chp FOREIGN KEY (pageid) REFERENCES pages ON UPDATE CASCADE ON DELETE CASCADE ); CREATE TABLE pagerev( revid SERIAL not null, pageid int not null, revdate timestamp, content TEXT, title varchar(255), CONSTRAINT pk_revid PRIMARY KEY (revid), CONSTRAINT fk_rev_page FOREIGN KEY (pageid) REFERENCES pages ON UPDATE CASCADE ON DELETE RESTRICT ); ALTER TABLE pages ADD CONSTRAINT fk_page_ref FOREIGN KEY (currentrev) REFERENCES pagerev(revid) ON UPDATE CASCADE ON DELETE RESTRICT;
To delete (drop) all tables use the following statement to remove them safely: SET SEARCH_PATH TO wikionwheels; ALTER TABLE pages DROP CONSTRAINT fk_page_ref; DROP DROP DROP DROP
TABLE TABLE TABLE TABLE
pagerev; cathaspages; pages; categories;
5) To assist with the inserting of the pages and revisions I’ve created a few SQL functions. Add them with the following statements: SET SEARCH_PATH to wikionwheels; CREATE OR REPLACE FUNCTION addPageAndLinkCat(IN _catid integer, IN _pageid integer,IN _title VARCHAR(255),out success INTEGER) LANGUAGE plpgsql AS $func$ BEGIN INSERT INTO pages(pageid,title) SELECT _pageid,_title WHERE NOT EXISTS( SELECT pageid FROM pages WHERE pageid=_pageid );
7
Wiki on Wheels
Anton Kirschhock
INSERT INTO cathaspages (catid,pageid) SELECT _catid,_pageid WHERE NOT EXISTS( SELECT catid,pageid FROM cathaspages WHERE catid=_catid AND pageid=_pageid ); success:=1; END $func$; CREATE OR REPLACE FUNCTION addRev(IN _revid INTEGER,IN _pageid INTEGER,IN _date DATE, IN _content TEXT,out success INTEGER) LANGUAGE plpgsql AS $func$ BEGIN INSERT INTO pagerev(revid,pageid,revdate,content) SELECT _revid,_pageid,_date,_content WHERE NOT EXISTS( SELECT 1 FROM pagerev WHERE revid = _revid AND pageid = _pageid ); success:=1; END $func$; CREATE OR REPLACE FUNCTION setCurrentRev(IN _revid INTEGER, IN _pageid INTEGER,out success INTEGER) LANGUAGE plpgsql AS $func$ BEGIN UPDATE pages SET currentrev = _revid WHERE pageid = _pageid; success:=1; END $func$; CREATE OR REPLACE FUNCTION deleteAll(out success INTEGER) LANGUAGE plpgsql AS $func$ BEGIN DELETE FROM cathaspages; UPDATE pages SET currentrev = null; DELETE FROM pagerev; DELETE FROM pages; DELETE FROM categories; success:=1; END $func$;
6) Database wise everything is done. Now the only thing is configure the console app through the config file, located at the folder of execution (same folder as the .exe). For the SQL server connection add the following key-value pairs:
8
Wiki on Wheels
Anton Kirschhock
SqlHost->somehost SqlDatabase->somedatabase SqlUser->someusername SqlPassword->somepassword SqlPort->someport
Add these combinations before the #END statement. There you go, the database side configuration is done.
The Code C# For reading the API I have used C#. This because C# has LINQ (Language Integrated Query). LINQ is built into the .net framework which is able to query through an Enumerable. Thanks to LINQ-To-Wiki we are able to get the API easily. While the query is still downloading, we are able to use operations on the query even before it is done, thanks to asynchronous operations. Also another reason to use C# is ADO.Net. ADO.Net (ActiveX Data Objects for .NET) is interface between the user application and the database level. Each database developer can create their own implementation by using the interfaces provided into the .Net framework. There are connectors for MsSQL (default in .net), MySQL, DB2 (oracle), PostgreSQL,…
Configuring the application The configuration file is using a key value pair to make it easy. You can use the following keys: LastStep WikiUri BotName SqlHost SqlDatabase SqlUser SqlPassword SqlPort
It’s important to know that there shouldn’t be an unnecessary space after the key or value. The correct value should be: ‘KEY->VALUE’ (Without the ‘ ofcourse). Also note that there is a way to comment using # in front of the comment text. There are also 2 comments #BEGIN and #END. These will be used in future support which could speed up the reading time of the file.
9
Wiki on Wheels
Anton Kirschhock
Bijlage 2: echte Wikipedia schema
10
Wiki on Wheels
Anton Kirschhock
Bijlage 3: Wiki-on-Wheels Schema
11
Wiki on Wheels
Anton Kirschhock