Haskell持久性w / esqueleto:读取整个表,并计算记录

时间:2015-07-12 01:15:02

标签: database haskell esqueleto

我有以下架构:

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编写一个能够返回表中记录数的函数?

谢谢!

1 个答案:

答案 0 :(得分:1)

  1. 您使用runSqlPersistMrunSqlPersistMPool等函数来评估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])
    
  2. 是的,你可以,但你必须包含一些额外的限制:

    dumpDbTbl :: (PersistEntity b, MonadIO m,
                  PersistEntityBackend b ~ SqlBackend) => SqlPersistT m [b]
    dumpDbTbl = map entityVal <$> (select . from $ return)
    
  3. 您使用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))