Skip to content

Instantly share code, notes, and snippets.

@tfausak
Created November 8, 2021 20:36
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save tfausak/ef90504d99cfef82c916284a46f9d495 to your computer and use it in GitHub Desktop.
Save tfausak/ef90504d99cfef82c916284a46f9d495 to your computer and use it in GitHub Desktop.
Persistent's `selectList` versus `selectSource` in Haskell with PostgreSQL.
{-# language DataKinds #-}
{-# language DerivingStrategies #-}
{-# language EmptyDataDecls #-}
{-# language FlexibleInstances #-}
{-# language GADTs #-}
{-# language GeneralizedNewtypeDeriving #-}
{-# language MultiParamTypeClasses #-}
{-# language OverloadedStrings #-}
{-# language QuasiQuotes #-}
{-# language StandaloneDeriving #-}
{-# language TemplateHaskell #-}
{-# language TypeApplications #-}
{-# language TypeFamilies #-}
{-# language UndecidableInstances #-}
import qualified Conduit
import qualified Control.Monad as Monad
import qualified Control.Monad.Logger as Logger
import qualified Control.Monad.IO.Class as IO
import qualified Control.Monad.Trans.Reader as Reader
import qualified Data.Bits as Bits
import qualified Data.IORef as IORef
import qualified Database.Persist as Persist
import qualified Database.Persist.Postgresql as Persist
import qualified Database.Persist.TH as Persist
import qualified System.Random as Random
$( Persist.share
[ Persist.mkPersist Persist.sqlSettings
, Persist.mkMigrate "userMigration"
] [Persist.persistLowerCase|
User
age Int
name String
deriving Eq Show
|] )
main :: IO ()
main = Logger.runNoLoggingT
. Persist.withPostgresqlConn "postgresql://postgres:password@localhost:5432/postgres"
. Reader.runReaderT
$ do
Persist.runMigration userMigration
let userFilters = [] :: [Persist.Filter User]
Persist.deleteWhere userFilters
Monad.replicateM_ 100000 $ do
age <- Random.randomIO
name <- Monad.replicateM 8 $ Random.randomRIO ('a', 'z')
Persist.insert_ User { userAge = age, userName = name }
ref <- IO.liftIO $ IORef.newIORef 0
Monad.when False $ do
users <- Persist.selectList userFilters []
Monad.forM_ users
$ IO.liftIO
. IORef.modifyIORef' ref
. Bits.xor
. userAge
. Persist.entityVal
Monad.when True
. Conduit.runResourceT
. Conduit.runConduit
$ Persist.selectSource userFilters []
Conduit..| Conduit.mapM_C
( IO.liftIO
. IORef.modifyIORef' ref
. Bits.xor
. userAge
. Persist.entityVal
)
val <- IO.liftIO $ IORef.readIORef ref
IO.liftIO $ print val
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment