Haskell persistent w/ esqueleto:读取整个 table,并对记录进行计数

Haskell persistent w/ esqueleto: read entire table, and count records

我有以下架构:

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
|]

现在说我要以[AdminChan]的形式获取admin_chantable中的所有记录。我怎样才能做到这一点?我有这个功能:

dumpDbTbl :: SqlPersistT IO [AdminChan]
dumpDbTbl = map entityVal <$> (select . from $ return)

1) 但是如何从 SqlPersistT IO 堆栈中取出 [AdminChan]? (请注意,我没有使用 yesod。)

2) 另外,是否可以重写上述函数,使其成为多态的,也可以与 BanHost table 一起使用?

3) 我如何使用 esqueleto 编写一个函数,它将 return table 中的记录数?

谢谢!

  1. 您使用类似 runSqlPersistM or 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])
    
  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))