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