]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Storage/Impl.hs
Code cleanup
[Rakka.git] / Rakka / Storage / Impl.hs
index c763a304f51f187b6625bcebcb6478ae6dfd0032..bedc9eaa2808d3142e5d4abf91cd00d724369401 100644 (file)
@@ -12,11 +12,14 @@ module Rakka.Storage.Impl
 
 import           Control.Concurrent
 import           Control.Concurrent.STM
+import           Control.Exception
 import           Control.Monad
 import           Data.Maybe
 import           Data.Set (Set)
 import qualified Data.Set as S
+import           Data.Time
 import           Network.HTTP.Lucu
+import           Network.HTTP.Lucu.Utils
 import           Network.URI
 import           Prelude hiding (words)
 import           Rakka.Attachment
@@ -24,6 +27,7 @@ import           Rakka.Page
 import           Rakka.Storage.DefaultPage
 import           Rakka.Storage.Repos
 import           Rakka.Storage.Types
+import           Rakka.W3CDateTime
 import           Subversion.Types
 import           Subversion.FileSystem
 import           Subversion.Repository
@@ -65,9 +69,7 @@ findAllPages repos rev = do reposPages   <- findAllPagesInRevision repos rev
 findChangedPages :: Repository -> RevNum -> RevNum -> IO (Set PageName)
 findChangedPages repos 0      newRev = findAllPages repos newRev
 findChangedPages repos oldRev newRev
-    = mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev]
-      >>=
-      return . S.unions
+    = liftM S.unions (mapM (findChangedPagesAtRevision repos) [oldRev + 1 .. newRev])
 
 
 getDirContents' :: Repository -> PageName -> Maybe RevNum -> IO [PageName]
@@ -106,7 +108,7 @@ startIndexManager :: FilePath -> Repository -> (Page -> IO Document) -> IO (TCha
 startIndexManager lsdir repos mkDraft
     = do chan  <- newTChanIO
          index <- openIndex indexDir revFile
-         forkIO (loop chan index)
+         _     <- forkIO (loop chan index `finally` closeDatabase index)
          return chan
     where
       indexDir = lsdir </> "index"
@@ -157,6 +159,7 @@ openIndex indexDir revFile
                               $ removeFile revFile
 
                      Right index <- openDatabase indexDir (Writer [Create []])
+                     addAttrIndex index "@mdate"         SeqIndex
                      addAttrIndex index "@type"          StrIndex
                      addAttrIndex index "@uri"           SeqIndex
                      addAttrIndex index "rakka:revision" SeqIndex
@@ -185,27 +188,48 @@ syncIndex' index revFile repos mkDraft
                mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages)
 
 
-searchIndex :: Database -> Condition -> IO [SearchResult]
+searchIndex :: Database -> Condition -> IO SearchResult
 searchIndex index cond
     = do (ids, hint) <- searchDatabase' index cond
-         mapM (fromId $ map fst hint) ids
+         let (total, words) = parseHint hint
+         pages <- mapM (fromId words) ids
+         return SearchResult {
+                      srTotal = total
+                    , srPages = pages
+                    }
     where
-      fromId :: [String] -> DocumentID -> IO SearchResult
+      parseHint :: [(String, Int)] -> (Int, [String])
+      parseHint xs
+          = let total = fromJust $ lookup "" xs
+                words = filter (/= "") $ map fst xs
+            in
+              (total, words)
+
+      fromId :: [String] -> DocumentID -> IO HitPage
       fromId words docId
           = do uri     <- getDocURI index docId
-               rev     <- getDocAttr index docId "rakka:revision"
-                          >>= return . read . fromJust
+               rev     <- unsafeInterleaveIO $
+                          liftM (read . fromJust)
+                                (getDocAttr index docId "rakka:revision")
+               lastMod <- unsafeInterleaveIO $
+                          liftM (zonedTimeToUTC . fromJust . parseW3CDateTime . fromJust)
+                                (getDocAttr index docId "@mdate")
+               summary <- unsafeInterleaveIO $
+                          getDocAttr index docId "rakka:summary"
                snippet <- unsafeInterleaveIO $
                           do doc <- getDocument index docId [NoAttributes, NoKeywords]
                              sn  <- makeSnippet doc words 300 80 80
-                             return (map toFragment sn)
-               return SearchResult {
-                            srPageName = decodePageName $ uriPath uri
-                          , srPageRev  = rev
-                          , srSnippet  = snippet
+                             return (trim (== Boundary) $ map toFragment sn)
+               return HitPage {
+                            hpPageName = decodePageName $ uriPath uri
+                          , hpPageRev  = rev
+                          , hpLastMod  = lastMod
+                          , hpSummary  = summary
+                          , hpSnippet  = snippet
                           }
 
       toFragment :: Either String (String, String) -> SnippetFragment
+      toFragment (Left "")      = Boundary
       toFragment (Left t)       = NormalText t
       toFragment (Right (w, _)) = HighlightedWord w
 
@@ -240,7 +264,7 @@ updateIndexRev revFile f = withFile revFile ReadWriteMode update
                     rev  <- if eof then
                                 return 0
                             else
-                                hGetLine h >>= return . read
+                                liftM read (hGetLine h)
                     rev' <- f rev
                     hSeek h AbsoluteSeek 0
                     hSetFileSize h 0