我有以下架构:
share [ mkPersist sqlSettings, mkMigrate "migrateAll" ] [persistLowerCase|
AdminChan
timestamp T.Text
name T.Text
msg T.Text
BanHost
timestamp T.Text
host T.Text
isBanned Bool
reason T.Text
|]
现在说我想以admin_chan
的形式获取[AdminChan]
表中的所有记录。我怎样才能做到这一点?我有这个功能:
dumpDbTbl :: SqlPersistT IO [AdminChan]
dumpDbTbl = map entityVal <$> (select . from $ return)
1)但是如何从[AdminChan]
堆栈中获取SqlPersistT IO
? (请注意,我没有使用yesod
。)
2)此外,是否可以重写上述函数,使其变为多态并且也可以与BanHost
表一起使用?
3)如何使用esqueleto
编写一个能够返回表中记录数的函数?
谢谢!
答案 0 :(得分:1)
您使用runSqlPersistM
或runSqlPersistMPool
等函数来评估IO
monad中的查询。例如:
dumpDbTbl :: (MonadIO m) => SqlPersistT m [AdminChan]
dumpDbTbl = map entityVal <$> (select . from $ return)
main :: IO ()
main = runStderrLoggingT $ withSqlitePool ":memory:" 4 $ \pool -> liftIO $ do
flip runSqlPersistMPool pool $ do
runMigration migrateAll
admins <- dumpDbTbl
liftIO $ print (admins :: [AdminChan])
是的,你可以,但你必须包含一些额外的限制:
dumpDbTbl :: (PersistEntity b, MonadIO m,
PersistEntityBackend b ~ SqlBackend) => SqlPersistT m [b]
dumpDbTbl = map entityVal <$> (select . from $ return)
您使用esqueleto函数countRows
:
countHostBans :: (MonadIO m) => SqlPersistT m [(T.Text, Int)]
countHostBans =
map (\(Value v, Value c) -> (v, c)) <$> (select $ from $ \banHost -> do
let c = countRows
groupBy (banHost ^. BanHostHost)
return (banHost ^. BanHostHost, c))