]> ruin.nu Git - yawbih.git/blob - Wiki.hs
dee41a10e38dbba467d315c164f5f7aff81b0885
[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 <- satisfy validChar
76         return (Text (c:[]))
77
78 pText = do
79         t <- many1 alphaNum--(noneOf ['\n','\r','[',']'])
80         return (Text t)
81
82 validChar ',' = True
83 validChar ';' = True
84 validChar '.' = True
85 validChar ':' = True
86 validChar '!' = True
87 validChar '?' = True
88 validChar '[' = True
89 validChar ']' = True
90 validChar '(' = True
91 validChar ')' = True
92 validChar '\'' = True
93 validChar '"' = True
94 validChar '=' = True
95 validChar '-' = True
96 validChar '%' = True
97 validChar '$' = True
98 validChar '£' = True
99 validChar '<' = True
100 validChar '>' = True
101 validChar '/' = True
102 validChar '\\' = True
103 validChar '|' = True
104 validChar _ = False
105
106
107 newtype PGB = PGB DBService
108
109 createPGB :: String -> String -> String -> String -> IO PGB
110 createPGB host database user password = let db = createDBService host database "" user password Nothing in return (PGB db)
111
112
113 testDB = createPGB "wave" "wiki" "wiki" "12wiki34db"
114
115 instance Backend PGB where
116
117         getCurrent (PGB db) key = do 
118                 result <- selectReturnTuples db $ "SELECT fulltext,timestamp FROM curtexts WHERE keyword="++tov key
119                 case result of
120                         [text,date]:_ -> return (Just (text,date))
121                         _ -> return Nothing
122
123         getList (PGB db) key = do
124                 list <- selectReturnTuples db $ "SELECT id, timestamp, author, comment from fulltexts WHERE keyword = "++tov key
125                 return $ map (\[id,date,author,comment] -> (id,date,author,comment)) list
126
127         get (PGB db) key id = return ""
128
129         setCurrent (PGB db) key id = do
130                 full <- selectReturnTuples db $ "SELECT keyword FROM fulltexts WHERE keyword="++tov key++" AND id='"++id++"'"
131                 cur <- selectReturnTuples db $ "SELECT keyword FROM curtexts WHERE keyword="++tov key
132                 case full of
133                         [[]] -> do
134                                 return False
135                         _  -> do
136                                 rows <- case cur of
137                                         [[]] -> do
138                                                 execute db $ "INSERT INTO current (keyword, id) VALUES ("++tov key++","++tov id++")"
139                                         _  -> do
140                                                 execute db $ "UPDATE current SET id = "++tov id++" WHERE keyword = "++tov key
141                                 if rows == 1 then return True
142                                         else return False 
143
144         update (PGB db) key text author comment = do
145                 rows <- execute db $ "INSERT INTO fulltexts (keyword,fulltext, author, comment) VALUES ("++tov key++","++tov text++","++tov author++","++tov comment++")"
146                 if rows == 0 then return ""
147                         else do
148                                 [[id]] <- selectReturnTuples db $ "SELECT currval('fulltexts_id_seq')" 
149                                 setCurrent (PGB db) key id
150                                 return id
151                         
152
153 tov :: String -> String
154 tov s = '\'':escapeQuery s++"'"
155                 
156