snaplet-postgresql-simple によって提供される DB アクセス関数は、HasPostgres
型クラスのインスタンスである任意のモナドで実行されます。通常、これはHandler
アプリケーションのモナドになります。
Handler
内で関数を使用することはできませんInitializer
。Initializer モナドの要点は、Web サーバーと Handler モナドを実行するために必要な初期状態のデータ型を設定することです。したがって、イニシャライザー内でハンドラーを実行することは本当に不可能です-もちろん、あるWebサーバーを別のWebサーバー内から実行している場合を除きます...いや。
したがって、2 つの選択肢があります。HasPostgres
のインスタンスを作成できますInitializer
。ただし、静的サーバーに接続していない限り、それはあまり意味がありません。デバッグを行っている場合、これは許容される場合があります。IO がデータベース機能を簡単にテストできるようにするために、時々これを行います。
instance HasPostgres IO where
getPostgresState = do
pool <- createPool (connect $ ConnectInfo "127.0.0.1" ...) ...
return $ Postgres pool
しかし、一般に、実稼働コードで使用するためにこのようなインスタンスを作成することは意味がありません。これは、データベースにアクセスする場合Initializer
、snaplet-postgresql-simple によって提供されるラッパーではなく、postgresql-simple 関数を直接使用する必要があることを意味します。そのため、pgPool アクセサー関数をエクスポートしました。次のようになります。
initDB :: SnapletInit b (DB b)
initDB = makeSnaplet "db" "cached database" Nothing $ do
pgs <- nestSnaplet "pgsql" pgsql pgsInit
let pool = pgPool $ extract pgs
results <- liftIO $ withResource pool (\conn -> query_ conn myQuery)
snaplet-postgresql-simple のauth backendで、この実際のライブの例を見ることができます。
アップデート:
ReaderT の HasPostgres インスタンスを提供する新しいバージョンの snaplet-postgresql-simple を hackage にアップロードしました。これにより、runReaderT を使用してこれをより簡単に実現できます。ドキュメントには、これの小さなコード スニペットがあります。