Browse Source

DB++

master
Denis Tereshkin 9 years ago
parent
commit
445dc8fecb
  1. 1
      mds.cabal
  2. 44
      src/ATrade/MDS/Database.hs

1
mds.cabal

@ -25,6 +25,7 @@ library
, libatrade , libatrade
, hslogger , hslogger
, time , time
, monad-loops
default-language: Haskell2010 default-language: Haskell2010
executable mds-exe executable mds-exe

44
src/ATrade/MDS/Database.hs

@ -8,11 +8,15 @@ import qualified Data.Text as T
import qualified Data.Vector as V import qualified Data.Vector as V
import ATrade.Types import ATrade.Types
import Data.Time.Clock import Data.Time.Clock
import Data.Time.Clock.POSIX
import Data.Maybe
import Control.Concurrent.MVar import Control.Concurrent.MVar
import Control.Concurrent import Control.Concurrent
import System.Log.Logger import System.Log.Logger
import Database.HDBC import Database.HDBC
import Database.HDBC.PostgreSQL import Database.HDBC.PostgreSQL
import Control.Monad
import Control.Monad.Loops
data TimeInterval = TimeInterval UTCTime UTCTime data TimeInterval = TimeInterval UTCTime UTCTime
@ -23,8 +27,7 @@ timeframeHour = Timeframe 3600
timeframeMinute = Timeframe 60 timeframeMinute = Timeframe 60
data DatabaseCommand = DBGet TickerId TimeInterval Timeframe | DBPut TickerId TimeInterval Timeframe (V.Vector Bar) data DatabaseCommand = DBGet TickerId TimeInterval Timeframe | DBPut TickerId TimeInterval Timeframe (V.Vector Bar)
data DatabaseResponse = DBData [(TimeInterval, V.Vector Bar)] | DBError T.Text data DatabaseResponse = DBOk | DBData [(TimeInterval, V.Vector Bar)] | DBError T.Text
data DatabaseConfig = DatabaseConfig { data DatabaseConfig = DatabaseConfig {
dbHost :: T.Text, dbHost :: T.Text,
dbDatabase :: T.Text, dbDatabase :: T.Text,
@ -43,19 +46,35 @@ startDatabase config = do
conn <- connectPostgreSQL (mkConnectionString config) conn <- connectPostgreSQL (mkConnectionString config)
cmdVar <- newEmptyMVar cmdVar <- newEmptyMVar
respVar <- newEmptyMVar respVar <- newEmptyMVar
tid <- forkFinally (dbThread conn cmdVar respVar) (cleanup conn cmdVar respVar) compVar <- newEmptyMVar
tid <- forkFinally (dbThread conn cmdVar respVar) (cleanup conn cmdVar respVar compVar)
return DatabaseInterface { return DatabaseInterface {
tid = tid, tid = tid,
getData = doGetData cmdVar respVar, getData = doGetData cmdVar respVar,
putData = doPutData cmdVar respVar } putData = doPutData cmdVar respVar }
where where
mkConnectionString = undefined mkConnectionString = undefined
dbThread = undefined dbThread conn cmdVar respVar = forever $ do
cleanup = undefined cmd <- readMVar cmdVar
handleCmd conn cmd >>= putMVar respVar
stopDatabase :: DatabaseInterface -> IO () whileM_ (isJust <$> tryReadMVar respVar) yield
stopDatabase db = undefined takeMVar cmdVar
cleanup conn cmdVar respVar compVar _ = disconnect conn >> putMVar compVar ()
handleCmd conn cmd = case cmd of
DBPut tickerId (TimeInterval start end) (Timeframe timeframeSecs) bars -> do
delStmt <- prepare conn "DELETE FROM bars WHERE timestamp > ? AND timestamp < ? AND ticker == ? AND timeframe == ?;"
execute delStmt [utcTimeToPosixSeconds start, utcTimeToPosixSeconds end, tickerId, timeframeSecs]
stmt <- prepare conn "INSERT INTO bars (ticker, timeframe, timestamp, open, high, low, close, volume)" ++
" values (?, ?, ?, ?, ?, ?, ?, ?); "
executeMany stmt (map barToSql $ V.toList bars)
return DBOk
DBGet tickerId interval@(TimeInterval start end) (Timeframe timeframeSecs) -> do
rows <- quickQuery' conn "SELECT timestamp, open, high, low, close, volume FROM bars WHERE ticker == ? AND timeframe == ? AND timestamp > ? AND timestamp < ?;" [tickerId, timeframeSecs, utcTimeToPosixSeconds start, utcTimeToPosixSeconds end]
return $ DBData [(interval, V.fromList $ map barFromResult rows)]
barFromResult = undefined
stopDatabase :: MVar () -> DatabaseInterface -> IO ()
stopDatabase compVar db = killThread (tid db) >> readMVar compVar
doGetData :: MVar DatabaseCommand -> MVar DatabaseResponse -> TickerId -> TimeInterval -> Timeframe -> IO [(TimeInterval, V.Vector Bar)] doGetData :: MVar DatabaseCommand -> MVar DatabaseResponse -> TickerId -> TimeInterval -> Timeframe -> IO [(TimeInterval, V.Vector Bar)]
doGetData cmdVar respVar tickerId timeInterval timeframe = do doGetData cmdVar respVar tickerId timeInterval timeframe = do
@ -66,13 +85,20 @@ doGetData cmdVar respVar tickerId timeInterval timeframe = do
DBError err -> do DBError err -> do
warningM "DB.Client" $ "Error while calling getData: " ++ show err warningM "DB.Client" $ "Error while calling getData: " ++ show err
return [] return []
_ -> do
warningM "DB.Client" "Unexpected response"
return []
doPutData :: MVar DatabaseCommand -> MVar DatabaseResponse -> TickerId -> TimeInterval -> Timeframe -> V.Vector Bar -> IO () doPutData :: MVar DatabaseCommand -> MVar DatabaseResponse -> TickerId -> TimeInterval -> Timeframe -> V.Vector Bar -> IO ()
doPutData cmdVar respVar tickerId timeInterval timeframe bars = do doPutData cmdVar respVar tickerId timeInterval timeframe bars = do
putMVar cmdVar (DBPut tickerId timeInterval timeframe bars) putMVar cmdVar (DBPut tickerId timeInterval timeframe bars)
resp <- takeMVar respVar resp <- takeMVar respVar
case resp of case resp of
DBData x -> return () DBOk -> return ()
DBError err -> do DBError err -> do
warningM "DB.Client" $ "Error while calling putData: " ++ show err warningM "DB.Client" $ "Error while calling putData: " ++ show err
return () return ()
_ -> do
warningM "DB.Client" "Unexpected response"
return []

Loading…
Cancel
Save