X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FStorage.hs;h=d88a336506a23dd162278ec8b69930ab18a46879;hb=044a917ed3908780479b759ac772e1545616c7fc;hp=fc5637d7b686dff5a6eefc900132e4641c7f5760;hpb=98e508613bb7a50a1f65998ce87f065df957b736;p=Rakka.git diff --git a/Rakka/Storage.hs b/Rakka/Storage.hs index fc5637d..d88a336 100644 --- a/Rakka/Storage.hs +++ b/Rakka/Storage.hs @@ -5,9 +5,15 @@ module Rakka.Storage , getPage , putPage + , deletePage , getPageA , putPageA + , deletePageA + + , searchPages + + , rebuildIndex ) where @@ -15,110 +21,72 @@ import Control.Arrow.ArrowIO import Control.Concurrent.STM import Control.Monad import Control.Monad.Trans -import Data.Set (Set) +import Data.Maybe +import Network.HTTP.Lucu import Rakka.Page -import Rakka.Storage.DefaultPage +import Rakka.Storage.Impl +import Rakka.Storage.Types import Subversion.Types -import System.Directory -import System.FilePath -import System.Log.Logger +import System.IO import Subversion.Repository -import Text.HyperEstraier - --- FIXME -import Data.Encoding -import Data.Encoding.UTF8 -import qualified Data.ByteString.Lazy.Char8 as C8 --- FIXME - -logger = "Rakka.Storage" - - -data Storage - = Storage { - stoIndexRevLocked :: !(TVar Bool) - , stoIndexRevFile :: !FilePath - , stoIndexDB :: !Database - , stoRepository :: !Repository - , stoMakeDraft :: !(Page -> IO Document) - } +import Text.HyperEstraier hiding (WriteLock) mkStorage :: FilePath -> Repository -> (Page -> IO Document) -> IO Storage mkStorage lsdir repos mkDraft - = do let indexDir = lsdir `combine` "index" - revFile = lsdir `combine` "indexRev" - - revLocked <- newTVarIO False - indexDB <- openIndex indexDir revFile - + = do chan <- startIndexManager lsdir repos mkDraft let sto = Storage { - stoIndexRevLocked = revLocked - , stoIndexRevFile = revFile - , stoIndexDB = indexDB - , stoRepository = repos - , stoMakeDraft = mkDraft + stoRepository = repos + , stoIndexChan = chan } - syncIndex sto return sto -getPage :: MonadIO m => Storage -> PageName -> m (Maybe Page) -getPage sto name - = liftIO $ loadDefaultPage name -- FIXME +getPage :: MonadIO m => Storage -> PageName -> Maybe RevNum -> m (Maybe Page) +getPage = ((liftIO .) .) . getPage' . stoRepository -putPage :: MonadIO m => Storage -> Maybe RevNum -> Page -> m () -putPage sto oldRev page - = error "FIXME: not implemented" +putPage :: MonadIO m => Storage -> Page -> m StatusCode +putPage sto page + = liftIO $ do st <- putPage' (stoRepository sto) page + syncIndex sto + return st -getPageA :: ArrowIO a => Storage -> a PageName (Maybe Page) -getPageA = arrIO . getPage +deletePage :: MonadIO m => Storage -> PageName -> m StatusCode +deletePage sto name + = liftIO $ do st <- deletePage' (stoRepository sto) name + syncIndex sto + return st -putPageA :: ArrowIO a => Storage -> a (Maybe RevNum, Page) () -putPageA = arrIO2 . putPage +getPageA :: ArrowIO a => Storage -> a (PageName, Maybe RevNum) (Maybe Page) +getPageA = arrIO2 . getPage -findAllPages :: Storage -> RevNum -> IO (Set PageName) -findAllPages sto revNum - = findAllDefaultPages -- FIXME +putPageA :: ArrowIO a => Storage -> a Page StatusCode +putPageA = arrIO . putPage --- casket を R/W モードで開く。成功したらそのまま返し、失敗したら --- indexDir と revFile を削除してから casket を R/W モードで開く。 -openIndex :: FilePath -> FilePath -> IO Database -openIndex indexDir revFile - = do ret <- openDatabase indexDir (Writer []) - case ret of - Right db - -> do debugM logger ("Opened an H.E. database on " ++ indexDir) - return db +deletePageA :: ArrowIO a => Storage -> a PageName StatusCode +deletePageA = arrIO . deletePage - Left err - -> do warningM logger ("Failed to open an H.E. database on " - ++ indexDir ++ ": " ++ show err) - indexExists <- doesDirectoryExist indexDir - when indexExists - $ removeDirectoryRecursive indexDir +searchPages :: MonadIO m => Storage -> Condition -> m [(PageName, RevNum)] +searchPages sto cond + = liftIO $ + do var <- newEmptyTMVarIO + atomically $ writeTChan (stoIndexChan sto) (SearchIndex cond var) + atomically $ takeTMVar var - revFileExists <- doesFileExist revFile - when revFileExists - $ removeFile revFile - Right db <- openDatabase indexDir (Writer [Create []]) - noticeM logger ("Created an H.E. database on " ++ indexDir) - - return db +rebuildIndex :: MonadIO m => Storage -> m () +rebuildIndex sto + = liftIO $ atomically $ writeTChan (stoIndexChan sto) RebuildIndex syncIndex :: Storage -> IO () syncIndex sto - = do Just page <- getPage sto "MainPage" - doc <- stoMakeDraft sto page - putStrLn "*** dumping draft..." - dumpDraft doc >>= C8.putStr . encodeLazy UTF8 - putStrLn "*** dumped" \ No newline at end of file + = atomically $ writeTChan (stoIndexChan sto) SyncIndex +