STRIX
StrixDocumentManagementForProgrammers: Revision 3

ďťż^ Strix Document Management s naglaskom na import dokumenata

^ O dokumentu Nove verzije ovog dokumenta bi se mogle naci na strix wikiju. Verzija 1: Matko Anđelinić, Srpanj 2005., Inicijalna verzija ^ Opis tablica ^^ Tablica "document" Glavna tablica. Zapisi i za dokumente i foldere. | id | integer | jedinstveni id dokumenta | | title | character varying(256) | naslov dokumenta (ne nuzno isto sto i filename) | | description | text | opis - text/html polje s opisom dokumenta | | activation_time | timestamp without time zone | vrijeme aktivacije dokumenta | | expiration_time | timestamp without time zone | vrijema isteka dokumenta | | creation_time | timestamp without time zone | vrijeme dokumenta (glavno datumsko polje na dokumentu) | | lang_id | integer | jezik u tablici lang | | allow_discussion | boolean | t/f - dopusteno otvaranje diskusije o dokumentu na forumu | | author_id | integer | zastarjelo polje za autora. pogledaj tablicu document_author | | parent_folder_id | integer | id parent foldera (zapis u istoj tablici) | | folder | boolean | t/f - radi li se o folderu ili o dokumentu | | locked | boolean | nije u upotrebi | | approved | boolean | dokument je odobren - ako je false dokument se pojavljuje u "waiting for approval" popisu | | keywords | text | kljucne rijeci | | edit_time | timestamp without time zone | zadnje vrijeme promjene zapisa | | edit_user | integer | korisnik koji je napravio zadnju promjenu (tablica users) | | source | text | free text polje - atribut "izvor dokumenta" | > PRIMARY KEY (id) ^^ Tablica "document_revision" Tablica koja veze verziju dokumenta s filenameom na filesystemu servera. Filename je samo filename i *ne* ukljucuje path (ni relativni ni apsolutni). | document_id | integer | id dokumenta | | version_num | smallint | redni broj verzija (nije vezan ni za jednu sekvencu) | | filename | character varying(256) | naziv dokumenta na filesystemu (bez patha, samo filename) | | filesize | integer | veličina fajla u bajtovima | | edit_time | timestamp without time zone | vrijeme promjene | | editor_id | integer | user koji je napravio promjenu | | last_author | integer | polje last author (mijenja se preko sucelja) | > PRIMARY KEY (document_id, version_num) Napomena 1: Verzioniranje ide redom 1, 2, .... Napomena 2: Iako folderi ne mogu imati verzije, za njih je svejedno potrebno imati zapis u ovoj tablici s version_num=0, te proizvoljnim vrijednostima u ostalim poljima. Napomena 3: Lokacija dokumenta na disku se racuna ovako: .pre $docman_dir/$document_id/$version_num/$filename gdje je $docman_dir - konfiguracijska varijabla iz etc/*.conf.php $document_id - id dokumenta (public.document.id ili public.document_revision.id) $version_num - redni broj verzije dokumenta (public.document_revision.version_num) $filename - vrijednost u polju public.document_revision.filename .pre ^^ Tablica "document_author" Vise zapisa po dokumentu. Informacija o autorima dokumenta koja se moze unositi i mijenjati preko sucelja. Po defaultu bi trebao biti barem jedan zapis s npr. osobom koja je uploadala dokument. | document_id | integer | id dokumenta | | version_num | smallint | verzija | | author_id | integer | autor iz tablice users | > PRIMARY KEY (document_id, version_num, author_id) > FOREIGN KEY (document_id, version_num) referencira "document_revision" ^^ Ostale tablice atributi komentari ^ Dozvole Koristi se STRIX-ov sustav dozvola - {search Category: ACL}. Oznaka za dokumente u ACL-u je 'file'. ^^ Tablice acl_user i acl_group Opis ACL-a nije u scopeu ovog dokumenta pa se nece opisivati. Vazno je da postoje te tablice, te zgodna plpgsql funkcija: > acl_userObjectAddPerm(user_id, 'file', document_id, perm) Za dokumente perm moze biti: * 'PERM_READ' ili integer vrijednost 1 * 'PERM_SUGGEST' ili integer vrijednost 2 * 'PERM_AUTHOR' ili integer vrijednost 4 * 'PERM_OWN' ili integer vrijednost -1 ili 8 ^^ Automatska, defaultna dodjela dozvola Uploaderu se, na razini baze (triggerom) automatski dodjeljuje OWN pravo. Bez obzira na sučelje kojim je zapis zavrsio u bazi. Uploader je osoba upisana u polju author_id prilikom inserta recorda u tablicu document. Za one koji zele znati vise, za to je zaduzen sljedeci zapis u tablici acl_users_default: .pre acl_id | default_sql --------+----------------------------------------------------------------------- file | SELECT 'file', NEW.id, author_id, -1 FROM document WHERE id = NEW.id .pre Dodatno, preporuka je da se OWN pravo dodijeli i svim osobama navedenim kao autori dokumenta u tablici document_author. > SELECT acl_userObjectAddPerm($user_id, 'file', $document_id, 'PERM_OWN'); ^ Mali primjer importa dokumenta koristenjem PHP libraryja Zamislimo slucaj da imamo na filesystemu dokument /data/tmp/dokument.doc kojeg zelimo importati u novi folder "Novi folder" koji bi se nalazio ispod postojeceg foldera XXXX sa id-jem 9. Stanje sadrzaja foldera XXXX prije pokretanja skripte za import: .pre plivaweb=# select id, title, folder, depth, ord from getDocumentTree(9); id | title | folder | depth | ord ----+-----------+--------+-------+----- 12 | Bayer.zip | f | 0 | 1 13 | Lilly.zip | f | 0 | 2 (2 rows) .pre Skripta za import: .pre <?php include_once("sysinc/stdlib.php"); include_once "docman.php"; // globalna varijabla koja (ako je true) libraryju govori da // pobrise OWN dozvole koje su automatski dodijeljene uploaderu (author_id) // preko triggera u bazi $PD_no_automatic_perms = false; $parent_folder = 9; $document_path = "/data/tmp/dokument.doc"; $in = array ( "title" => "Novi folder" , "description" => "" , "creation_time" => strftime("%Y-%m-%d") , "lang_id" => "1" , "allow_discussion" => "t" , "author_id" => "4" , "approved" => "t" , "keywords" => "testni folder, document import" , "edit_time" => "" , "edit_user" => "" , "source" => "" , "folder" => "t" ); $folder = PlivawebDocuments::createFolder($parent_folder, $in); if (PlivawebDocumentsError::isError($folder)) die ($folder->text); //ako smo ovdje u varijabli $folder imamo id novokreiranog foldera $in = array ( "title" => "Moj dokument" , "description" => "Dokument koji sam uploadao" , "creation_time" => strftime("%Y-%m-%d") , "lang_id" => 1 , "allow_discussion" => "t" , "author_id" => 3 , "approved" => "t" , "keywords" => "" , "edit_time" => strftime("%Y-%m-%d") , "edit_user" => 3 , "source" => "" , "attributes" => array() , "local_file_name" => $document_path ); $did = PlivawebDocuments::addDocument($folder, $in); if (PlivawebDocumentsError::isError($did)) die ($did->text); echo "Document created"; ?> .pre Pokrenuta skripta: > $ php4 docmanimport-example.php plivaweb Stanje sadrzaja foldera XXXX poslije pokretanja skripte za import: .pre plivaweb=# select id, title, folder, depth, ord from getDocumentTree(9); id | title | folder | depth | ord ------+--------------+--------+-------+----- 4949 | Novi folder | t | 0 | 3 4950 | Moj dokument | f | 1 | 4 12 | Bayer.zip | f | 0 | 6 13 | Lilly.zip | f | 0 | 7 (4 rows) .pre Napomena 1: PHP library u `inc/docman.php` nije ni blizu kompletan i 100% fail safe, ali je dobar start za nekoga tko zeli importati dokumente kroz skriptu. Napomena 2: Nema razloga da se ne napise skripta u nekom drugom jeziku koja bi direktno pisala po document* tablicama pridrzavajuci se gore opisanih pravila. ^ Dodatak: Funkcije za dohvat podataka Postoji niz funkcija za rukovanje (dohvacanje podataka). One su mahom rekurzivne. Popis tih plpgsql funkcija, zajedno s implementacijom moze se naci u tables2/docman.sql. Najcesce koristena takva funkcija je `getDocumentTree(folder_id integer)` koja vraca popis zapisa iz document tablicom skupa s dvije dodatne kolone depth (dubina, razina) te ord (redoslijed po kriteriju folder, title) Npr. .pre plivaweb=# select id, title, folder, depth, ord from getDocumentTree(26); id | title | folder | depth | ord -----+------------------------------------+--------+-------+----- 27 | forms | t | 0 | 1 28 | AC form | f | 1 | 2 426 | ChemClient Izjava | f | 1 | 3 427 | Formular za publikacije | f | 1 | 4 417 | HTS_form.pdf | f | 1 | 5 418 | New_PL_form.pdf | f | 1 | 6 419 | New_PL_form.xls | f | 1 | 7 422 | PK&M form | f | 1 | 8 29 | Publications Form | f | 1 | 9 428 | Rjesenje GO | f | 1 | 10 429 | Zahtjev za nabavu | f | 1 | 11 33 | instructions | t | 0 | 12 35 | LabNotebooks law.pdf | f | 1 | 13 421 | Pravilnik za pisanje lab. dnevnika | f | 1 | 14 420 | Upute o kretanju NII.pdf | f | 1 | 15 30 | instruments | t | 0 | 16 31 | instruments_development.xls | f | 1 | 17 32 | instruments_research.xls | f | 1 | 18 37 | presentations | t | 0 | 19 (19 rows) .pre Preporuka je, ne koristiti ovu funkciju bas za svaku moguci dohvat dokumenata, jer dodavanje WHERE uvjeta nad ovakav upit nece nimalo ubrzati dohvat podataka. Ako bi se dodao Where uvjet, svejedno bi se za svaki upit izgenerirao kompletan result set nakon cega se tek radi filtriranje. Bolje rjesenje je da se za svaku specificnu upotrebu pri kojoj je bitna efikasnost pise svoja rekurzivna funkcija. *Napomena*: Iako to nije slucaj sa funkcijama u tables2/docman.sql, zgodno je dodati STABLE u definiciji takve funkcije sto bi moglo bitno ubrzati te funkcije u nekim slucajevima. (Npr. u sucajevima kada se u jednom upitu radi visestruko pozivanje iste funkcije s istim parametrima).