X-Git-Url: http://git.cielonegro.org/gitweb.cgi?a=blobdiff_plain;f=Rakka%2FStorage.hs;h=fc5637d7b686dff5a6eefc900132e4641c7f5760;hb=98e508613bb7a50a1f65998ce87f065df957b736;hp=d830131d962b5c2eeb6fb3f6acc43e113a14650a;hpb=484e15845d9c06d0fa62044d3b6b3ff8c78a6e04;p=Rakka.git diff --git a/Rakka/Storage.hs b/Rakka/Storage.hs index d830131..fc5637d 100644 --- a/Rakka/Storage.hs +++ b/Rakka/Storage.hs @@ -4,26 +4,121 @@ module Rakka.Storage , mkStorage -- private , getPage - , savePage + , putPage + + , getPageA + , putPageA ) where +import Control.Arrow.ArrowIO +import Control.Concurrent.STM +import Control.Monad +import Control.Monad.Trans +import Data.Set (Set) import Rakka.Page import Rakka.Storage.DefaultPage +import Subversion.Types +import System.Directory +import System.FilePath +import System.Log.Logger +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) + } -data Storage = Storage -- FIXME +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 + let sto = Storage { + stoIndexRevLocked = revLocked + , stoIndexRevFile = revFile + , stoIndexDB = indexDB + , stoRepository = repos + , stoMakeDraft = mkDraft + } -mkStorage :: IO Storage -- FIXME -mkStorage = return Storage + syncIndex sto + return sto -getPage :: Storage -> PageName -> IO (Maybe Page) +getPage :: MonadIO m => Storage -> PageName -> m (Maybe Page) getPage sto name - = loadDefaultPage name -- FIXME + = liftIO $ loadDefaultPage name -- FIXME -savePage :: Storage -> PageName -> Page -> IO () -savePage sto name page +putPage :: MonadIO m => Storage -> Maybe RevNum -> Page -> m () +putPage sto oldRev page = error "FIXME: not implemented" + + +getPageA :: ArrowIO a => Storage -> a PageName (Maybe Page) +getPageA = arrIO . getPage + + +putPageA :: ArrowIO a => Storage -> a (Maybe RevNum, Page) () +putPageA = arrIO2 . putPage + + +findAllPages :: Storage -> RevNum -> IO (Set PageName) +findAllPages sto revNum + = findAllDefaultPages -- FIXME + + +-- 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 + + Left err + -> do warningM logger ("Failed to open an H.E. database on " + ++ indexDir ++ ": " ++ show err) + + indexExists <- doesDirectoryExist indexDir + when indexExists + $ removeDirectoryRecursive indexDir + + revFileExists <- doesFileExist revFile + when revFileExists + $ removeFile revFile + + Right db <- openDatabase indexDir (Writer [Create []]) + noticeM logger ("Created an H.E. database on " ++ indexDir) + + return db + + +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