TLQ72DSJD7GGPWN6HGBHAVPBRQFKEQ6KSK43U7JWWID4ZWAF47JAC
MXLZBRQNXRIJ4BTAEDSLA4N5PABEG7GMWSM7GS4ACJQ6BE4PVAKQC
LUM4VQJIHJKQWWD5NVWTVSNPKQTMGQQICTFOTM6W4BMME2G3G5RQC
LAROLAYUGJ4Q5AEFV5EJMIA2ZKBNCBWHHHPCJ3CKCNIUIYUKRFVQC
MWUPXTBF2LATVOJLJTXSDFB3OMFGMXDNETWJA3JHUOUBTUJ7WJAAC
75N3UJ4JK56KXF56GASGPAWLFYGJDETVJNYTF4KXFCQM767JUU5AC
WO2MINIF4TXOHWSE7JWXRZYN64XRVLYIRFMF4SMPSOXKA2V77KMQC
EMVTF2IWNQGRL44FC4JNG5FYYQTZSFPNM6SOM7IAEH6T7PPK2NVAC
64VI73NPSFNWTL6UXM6YHRFLNJZ3NUJ2R3CL53MO2HSZWFGBIRTQC
64C6AWH66FDKU6UE6Z6JPX2J2GBM2JOPTH2GL6LHKAIUBGNGDZ5AC
WFZDMVUXZ2KPTMRAZGEYHKEJTKOKWVYCXKKAKQ7K6I5TMSLBUJ4QC
TZQJVHBAMDNWDBYCDE3SDVGBG2T5FOE3J5JAD6NENRW36XBHUUFQC
FRPWIKCNGK6PM6VCKEHEUG5A2LWL7WFN66L4CPQ7DLN4WAS3TIZQC
NVOCQVASZWTKQJG7GPH7KHKZZR7NUG4WLV5YY4KAIRPCJRWCZPIAC
Y35QCWYW2OTZ27ZVTH2BA3XJTUCJ2WMLKU32ZCOCDY3AW7TIZXRAC
P6NR2CGXCWAW6GXXSIXCGOBIRAS2BM4LEM6D5ADPN4IL7TMW6UVAC
GKGVYBZGPJXO7N7GLHLRNYQPXFHBQSNQN53OKRFCXLQEYDTC5I4QC
2OIPAQCBDIUJBXB4K2QVP3IEBIUOCQHSWSWFVMVSVZC7GHX2VK7AC
RSEB2NFGUBTFESE5BJKDUVQL5Y5ZVGY5O4CJX2LNP63MS3NRHHZQC
NTPC7KJEAPA34SBIA74FVQSJXYNW32RIUQTHUSUTKMEUCPLUIBJAC
N4NDAZYTLSI2W22KT3SYXL257DBMSH3UT2BXOYM7LH7FSZAY4RLAC
7DBNV3GV773FH5ZLQWFX4RBOS4Q3CIK2RYZNNABY3ZOETYZCXRNQC
4QX5E5ACVN57KJLCWOM4JEI6JSV4XZNCWVYPOTKSOMUW3SOMCNJAC
bidSeconds bid = toRational $ bid ^. seconds
bidAmount bid = toRational $ bid ^. (btcAmount . btc)
costRatio bid = bidSeconds bid / bidAmount bid
secs bid = toRational $ bid ^. bidSeconds
btc bid = toRational $ bid ^. (bidAmount . satoshis)
costRatio bid = secs bid / btc bid
winFraction = (toRational $ remainder ^. btc) / (toRational $ x ^. (btcAmount . btc))
remainderSeconds = Seconds . round $ winFraction * (toRational $ x ^. seconds)
winFraction = (toRational $ remainder ^. satoshis) / (toRational $ x ^. (bidAmount . satoshis))
remainderSeconds = Seconds . round $ winFraction * (toRational $ x ^. bidSeconds)
sqliteQDB :: SQLiteHandle -> IO (QDB (EitherT Text IO) SQLiteHandle)
sqliteQDB db = do
_ <- defineTableOpt db True eventTable
_ <- defineTableOpt db True auctionTable
return $ QDB
{ recordEvent = recordEvent'
, readWorkIndex = readWorkIndex'
, newAuction = newAuction'
, readAuction = readAuction'
, recordBid = recordBid'
, readBids = readBids'
, createUser = createUser'
}
recordEvent' :: LogEntry -> ReaderT SQLiteHandle (EitherT Text IO) ()
recordEvent' (LogEntry ba ev) = do
db <- ask
lift . lift . void $ insertRow db "workEvents"
[ ("btcAddr", ba ^. address ^. from packed)
, ("event", unpack (eventName ev))
, ("eventTime", formatSqlTime (logTime ev))
]
readWorkIndex' :: ReaderT SQLiteHandle (EitherT Text IO) WorkIndex
readWorkIndex' = do
db <- ask
let selection = execStatement db "SELECT btcAddr, event, eventTime from workEvents"
rows <- lift . EitherT $ fmap (over _Left pack) selection
return . intervals . catMaybes $ fmap parseLogEntry (join rows)
newAuction' :: Auction -> ReaderT SQLiteHandle (EitherT Text IO) AuctionId
newAuction' a = do
db <- ask
_ <- lift . lift $ insertRow db "auctions"
[ ("raiseAmount", show $ a ^. (raiseAmount . btc))
, ("eventTime", formatSqlTime $ a ^. endsAt)
]
lift . lift . fmap (AuctionId . fromInteger) $ getLastRowID db
readAuction' :: AuctionId -> ReaderT a (EitherT Text IO) Auction
readAuction' (AuctionId aid) = do
db <- ask
let selection = execParamStatement db
"SELECT raiseAmount, endsAt FROM auctions WHERE ROWID = :aid"
[("aid", Int aid)]
rows <- lift . EitherT $ fmap (over _Left pack) selection
newtype PLogEntry = PLogEntry LogEntry
makePrisms ''PLogEntry
recordBid' :: UTCTime -> Bid -> ReaderT a (EitherT Text IO) ()
recordBid' = undefined
readBids' :: AuctionId -> ReaderT a (EitherT Text IO) [(UTCTime, Bid)]
readBids' = undefined
instance FromRow PLogEntry where
fromRow =
let workEventParser = WorkEvent <$> (field >>= nameEvent) <*> field
logEntryParser = LogEntry <$> (fmap BtcAddr field) <*> workEventParser
in fmap PLogEntry logEntryParser
parseLogEntry :: Row Value -> Maybe LogEntry
parseLogEntry row = do
a <- lookup "btcAddr" row >>= valueAddr
t <- lookup "eventTime" row >>= valueTime
ev <- lookup "event" row >>= (valueEvent t)
return $ LogEntry a ev
parseAuction :: Row Value -> Maybe Auction
parseAuction row =
Auction <$> (lookup "raiseAmount" row >>= valueBTC)
<*> (lookup "endsAt" row >>= valueTime)
instance FromRow PAuction where
fromRow =
let auctionParser = Auction <$> (fmap BTC field) <*> field
in fmap PAuction auctionParser
valueBTC :: Value -> Maybe BTC
valueBTC (Int i) _ = Just $ BTC i
valueBTC _ = Nothing
recordEvent' :: LogEntry -> ReaderT Connection IO ()
recordEvent' logEntry = do
conn <- ask
lift $ execute conn
"INSERT INTO work_events (btc_addr, event_type, event_time) VALUES (?, ?, ?)"
(logEntry ^. (from _PLogEntry))
valueAddr :: Value -> Maybe BtcAddr
valueAddr (Text t) = parseBtcAddr $ pack t
valueAddr _ = Nothing
readWorkIndex' :: ReaderT Connection IO WorkIndex
readWorkIndex' = do
conn <- ask
rows <- lift $ query_ conn
"SELECT btc_addr, event_type, event_time from workEvents"
lift . return . workIndex $ fmap (^. _PLogEntry) rows
valueTime :: Value -> Maybe UTCTime
valueTime (Text t) = parseTime defaultTimeLocale "%c" t
valueTime _ = Nothing
newAuction' :: Auction -> ReaderT Connection IO AuctionId
newAuction' auc = do
conn <- ask
lift $ execute conn
"INSERT INTO auctions (raise_amount, end_time) VALUES (?, ?)"
(auc ^. (raiseAmount . satoshis), auc ^. auctionEnd)
lift . fmap AuctionId $ lastInsertRowId conn
valueEvent :: UTCTime -> Value -> Maybe WorkEvent
valueEvent t (Text "start") = Just (StartWork t)
valueEvent t (Text "stop") = Just (StopWork t)
valueEvent _ _ = Nothing
readAuction' :: AuctionId -> ReaderT Connection IO (Maybe Auction)
readAuction' (AuctionId aid) = do
conn <- ask
rows <- lift $ query conn
"SELECT raise_amount, end_time FROM auctions WHERE ROWID = ?"
(Only aid)
lift . return . headMay $ fmap (^. _PAuction) rows
formatSqlTime :: UTCTime -> String
formatSqlTime t = formatTime defaultTimeLocale "%c" t
recordBid' :: AuctionId -> Bid -> ReaderT Connection IO ()
recordBid' (AuctionId aid) bid = do
conn <- ask
lift $ execute conn
"INSERT INTO bids (auction_id, user_id, bid_seconds, bid_amount, bid_time) values (?, ?, ?, ?, ?)"
(aid, bid ^. bidUser, bid ^. bidSeconds, bid ^. bidAmount, bid ^. bidTime)
eventTable :: SQLTable
eventTable = Table "workEvents"
[ Column "btcAddr" (SQLVarChar 256) []
, Column "event" (SQLVarChar 64) []
, Column "eventTime" (SQLDateTime DATETIME) []
] []
readBids' :: AuctionId -> ReaderT Connection IO [(UTCTime, Bid)]
readBids' = undefined
auctionTable :: SQLTable
auctionTable = Table "auctions"
[ Column "raiseAmouont" (SQLInt BIG False False) []
, Column "endsAt" (SQLDateTime DATETIME) []
] []
createUser' :: User -> ReaderT Connection IO UserId
createUser' = undefined
sqliteQDB :: QDB IO Connection
sqliteQDB = QDB
{ recordEvent = recordEvent'
, readWorkIndex = readWorkIndex'
, newAuction = newAuction'
, readAuction = readAuction'
, recordBid = recordBid'
, readBids = readBids'
, createUser = createUser'
}
eventName :: WorkEvent -> Text
eventName (StartWork _) = "start"
eventName (StopWork _) = "stop"
eventName :: EventType -> Text
eventName StartWork = "start"
eventName StopWork = "stop"
nameEvent :: MonadPlus m => Text -> m EventType
nameEvent "start" = return StartWork
nameEvent "stop" = return StopWork
nameEvent _ = mzero
parseJSON (Object jv) = do
t <- jv .: "type" :: A.Parser Text
case t of
"start" -> StartWork <$> jv .: "timestamp"
"stop" -> StopWork <$> jv .: "timestamp"
_ -> mzero
parseJSON (Object jv) =
WorkEvent <$> (jv .: "type" >>= nameEvent) <*> jv .: "timestamp"
intervals :: Foldable f => f LogEntry -> WorkIndex
intervals logEntries =
let logSum = F.foldl' appendLogEntry MS.empty logEntries
in MS.map (bimap (fmap event) (fmap workInterval)) $ logSum
workIndex :: Foldable f => f LogEntry -> WorkIndex
workIndex logEntries =
let logSum :: RawIndex
logSum = F.foldl' appendLogEntry MS.empty logEntries
in MS.map (bimap (fmap (^. event)) (fmap workInterval)) $ logSum
appendLogEntry workIndex entry =
let acc = reduceToIntervals $ pushEntry entry workIndex
in insert (btcAddr entry) acc workIndex
appendLogEntry idx entry =
let acc = reduceToIntervals $ pushEntry entry idx
in insert (entry ^. btcAddr) acc idx