X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FStorage%2FImpl.hs;h=e1bad11015a987b32d95d079594ae731550f85fb;hb=fcddebcc3cc02ae8d1904b9338334d538019e74a;hp=fed687f3c1266e992efc7973838cf8f41ced0ffb;hpb=e85b652169f502cffe1f6f7f927d8990e9c11499;p=Rakka.git diff --git a/Rakka/Storage/Impl.hs b/Rakka/Storage/Impl.hs index fed687f..e1bad11 100644 --- a/Rakka/Storage/Impl.hs +++ b/Rakka/Storage/Impl.hs @@ -16,19 +16,24 @@ 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 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 import System.Directory import System.FilePath import System.IO +import System.IO.Unsafe import System.Log.Logger import Text.HyperEstraier hiding (WriteLock) @@ -63,9 +68,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] @@ -104,7 +107,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) return chan where indexDir = lsdir "index" @@ -155,6 +158,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 @@ -183,16 +187,50 @@ syncIndex' index revFile repos mkDraft mapM_ (updateIndex index repos mkDraft newRev) (S.toList pages) -searchIndex :: Database -> Condition -> IO [(PageName, RevNum)] +searchIndex :: Database -> Condition -> IO SearchResult searchIndex index cond - = searchDatabase index cond >>= mapM fromId + = do (ids, hint) <- searchDatabase' index cond + let (total, words) = parseHint hint + pages <- mapM (fromId words) ids + return SearchResult { + srTotal = total + , srPages = pages + } where - fromId :: DocumentID -> IO (PageName, RevNum) - fromId docId - = do uri <- getDocURI index docId - rev <- getDocAttr index docId "rakka:revision" - >>= return . read . fromJust - return (decodePageName $ uriPath uri, rev) + 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 <- 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 (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 updateIndex :: Database @@ -225,7 +263,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