]> gitweb @ CieloNegro.org - Rakka.git/blobdiff - Rakka/Storage.hs
Implemented makeDraft and others
[Rakka.git] / Rakka / Storage.hs
index d830131d962b5c2eeb6fb3f6acc43e113a14650a..fc5637d7b686dff5a6eefc900132e4641c7f5760 100644 (file)
@@ -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