]> ruin.nu Git - yawbih.git/blob - Wiki.hs
keyword field and link instead of button
[yawbih.git] / Wiki.hs
1 module Wiki (
2         Backend (getCurrent,getList,get,setCurrent,update)
3         ,PGB
4         ,createPGB
5         ,Markup (Text, Paragraph, Link)
6         ,Document
7         ,wikiParser
8
9 ) where
10
11 import Dbconnect
12 import Data.Char
13 import Text.ParserCombinators.Parsec
14
15 class Backend a where
16         --Keyword -> (Full text,date)
17         getCurrent :: a -> String -> IO (Maybe (String,String))
18
19         --Keyword -> [(id,date,author,comment)]
20         getList :: a -> String -> IO [(String, String, String, String)]
21
22         --Keyword -> id -> Full text
23         get :: a -> String -> String -> IO String
24
25         --Keyword -> id -> ()
26         setCurrent :: a -> String -> String -> IO Bool
27
28         --Keyword -> Full text -> id
29         update :: a -> String -> String -> String -> String -> IO String
30
31 data Markup = Text String
32         | Paragraph 
33         | Link String String
34
35 type Document = [Markup]
36
37 wikiParser :: GenParser Char st Document        
38 wikiParser = do 
39         s <- (try (pPara) 
40                 <|> pSpace 
41                 <|> try (pLinkLong)
42                 <|> try (pLink)
43                 <|> pOtherChar
44                 <|> pText)
45         ss <- (wikiParser <|> return [])
46         return (s:ss)
47
48 pPara = do
49         pEol
50         pEol
51         return (Paragraph)
52
53
54 pSpace = do
55         space 
56         return (Text " ")
57
58 pEol = char '\n' <|> do
59         char '\r'
60         char '\n'
61
62 pLinkLong = do
63         string "[["
64         l <- many1 $ noneOf ['|']
65         char '|'
66         d <- many1 $ noneOf "]" 
67         string "]]"
68         return (Link l d)
69 pLink = do
70         string "[["
71         l <- many1 $ noneOf "]"
72         string "]]"
73         return (Link l l)
74 pOtherChar = do
75         c <- oneOf ",;.:!?[]()\'\"=-%$£<>/\\|"
76         return (Text (c:[]))
77
78 pText = do
79         t <- many1 alphaNum--(noneOf ['\n','\r','[',']'])
80         return (Text t)
81
82
83 newtype PGB = PGB DBService
84
85 createPGB :: String -> String -> String -> String -> IO PGB
86 createPGB host database user password = let db = createDBService host database "" user password Nothing in return (PGB db)
87
88
89 testDB = createPGB "wave" "wiki" "wiki" "12wiki34db"
90
91 instance Backend PGB where
92
93         getCurrent (PGB db) key = do 
94                 result <- selectReturnTuples db $ "SELECT fulltext,timestamp FROM curtexts WHERE keyword="++tov key
95                 case result of
96                         [text,date]:_ -> return (Just (text,date))
97                         _ -> return Nothing
98
99         getList (PGB db) key = do
100                 list <- selectReturnTuples db $ "SELECT id, timestamp, author, comment from fulltexts WHERE keyword = "++tov key
101                 return $ map (\[id,date,author,comment] -> (id,date,author,comment)) list
102
103         get (PGB db) key id = return ""
104
105         setCurrent (PGB db) key id = do
106                 full <- selectReturnTuples db $ "SELECT keyword FROM fulltexts WHERE keyword="++tov key++" AND id='"++id++"'"
107                 cur <- selectReturnTuples db $ "SELECT keyword FROM curtexts WHERE keyword="++tov key
108                 case full of
109                         [[]] -> do
110                                 return False
111                         _  -> do
112                                 rows <- case cur of
113                                         [[]] -> do
114                                                 execute db $ "INSERT INTO current (keyword, id) VALUES ("++tov key++","++tov id++")"
115                                         _  -> do
116                                                 execute db $ "UPDATE current SET id = "++tov id++" WHERE keyword = "++tov key
117                                 if rows == 1 then return True
118                                         else return False 
119
120         update (PGB db) key text author comment = do
121                 rows <- execute db $ "INSERT INTO fulltexts (keyword,fulltext, author, comment) VALUES ("++tov key++","++tov text++","++tov author++","++tov comment++")"
122                 if rows == 0 then return ""
123                         else do
124                                 [[id]] <- selectReturnTuples db $ "SELECT currval('fulltexts_id_seq')" 
125                                 setCurrent (PGB db) key id
126                                 return id
127                         
128
129 tov :: String -> String
130 tov s = '\'':escapeQuery s++"'"
131                 
132