Advertisement
Guest User

FileDB

a guest
May 11th, 2014
247
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. module FileDB where
  2.  
  3. import Control.Monad
  4. import qualified Data.Text as T
  5. import qualified Data.Text.IO as T
  6. import qualified Data.Map.Strict as M
  7. import Data.Maybe
  8. import Control.Applicative
  9. import System.IO
  10. import Control.Monad.Reader
  11.  
  12. type Key   = T.Text
  13. type Row   = [T.Text]
  14. type Index = M.Map Key Int
  15.  
  16. data Table = Table {
  17.   handle    :: Handle,
  18.   index     :: Index }
  19.   deriving (Show,Eq)
  20.  
  21. type TableM = ReaderT Table IO
  22.  
  23. runDB :: Table -> TableM a -> IO a
  24. runDB = flip runReaderT
  25.  
  26. getKeys :: TableM [Key]
  27. getKeys = M.keys <$> asks index
  28.  
  29. getRow :: Key -> TableM (Maybe Row)
  30. getRow k = do
  31.   h  <- asks handle
  32.   ix <- asks index
  33.   case M.lookup k ix of
  34.     Nothing -> return Nothing
  35.     Just i  -> do liftIO $ hSeek h AbsoluteSeek (toInteger i)
  36.                   Just . tail . T.words <$> liftIO (T.hGetLine h)
  37.  
  38. mkIndex :: Handle -> IO Index
  39. mkIndex h = M.fromList <$>
  40.   (untilM (hIsEOF h) $ do
  41.     x <- hTell h
  42.     (t:_) <- T.words <$> T.hGetLine h
  43.     return (t, fromInteger x))
  44.  
  45. untilM :: IO Bool -> IO a -> IO [a]
  46. untilM p a = do
  47.   t <- p
  48.   if t then return [] else do x <- a; xs <- untilM p a; return (x:xs)
  49.  
  50. openTable :: FilePath -> IO Table
  51. openTable f = do
  52.   h  <- openFile f ReadMode
  53.   ti <- mkIndex h
  54.   return $ Table { handle = h, index = ti }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement