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
-
-
-data Storage = Storage -- FIXME
-
-
-mkStorage :: Storage -- FIXME
-mkStorage = Storage
+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)
+ }
+
+
+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
+ }
+
+ syncIndex sto
+ return sto
getPage :: MonadIO m => Storage -> PageName -> m (Maybe Page)
putPageA :: ArrowIO a => Storage -> a (Maybe RevNum, Page) ()
-putPageA = arrIO2 . putPage
\ No newline at end of file
+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