2017年9月26日火曜日

PersistentのEsqueleto

PersistentのEsqueleto


夏が終わってさらに体が焼酎臭いのですが、Esqueletoなるものを発見したのちょっと触って見ました。

読み方がわからないので「えすきゅーぅうれぇっちゅ」とでもいうのか、まぁどうでもいいとして



こんなんを「えすきゅーぅうれぇっちゅ」を使って

mysql> select * from author as a left join blog as b on a.id=b.author;
+----+----------------------------------------------+------+------+--------------------------------------------------------------------------------------+--------+
| id | name                                         | age  | id   | title                                                                                | author |
+----+----------------------------------------------+------+------+--------------------------------------------------------------------------------------+--------+
|  1 | メンチョida(実在しない人物です)              |   40 |    1 | 休みあけ飲みすぎで体調不良です                                                       |      1 |
|  1 | メンチョida(実在しない人物です)              |   40 |    2 | DriverManagerDataSourceがテストのためだって誰が俺に教えてくれる?                     |      1 |
+----+----------------------------------------------+------+------+--------------------------------------------------------------------------------------+--------+
ってやってみたい

コード


{-# LANGUAGE TemplateHaskell #-}
{-# LANGUAGE TypeFamilies #-}
{-# LANGUAGE OverloadedStrings #-}
{-# LANGUAGE GADTs #-}
{-# LANGUAGE QuasiQuotes #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE MultiParamTypeClasses #-}
{-# LANGUAGE GeneralizedNewtypeDeriving #-}

import Database.Persist.MySQL
import Database.Persist.TH
import Control.Monad (guard)
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
import Control.Monad.Logger (runNoLoggingT, NoLoggingT)
import Control.Monad.IO.Class (liftIO)
import Data.Text
import qualified Database.Esqueleto as E
import Database.Esqueleto ((^.))

share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistLowerCase|
Author
    name Text sqltype=varchar(32)
    age Int Maybe
    deriving(Show)
Blog
    title Text sqltype=varchar(128)
    author AuthorId
    deriving(Show)
|]

main :: IO ()
main = do
  dbInit
  blogs <- esqueletoSay
  mapM_ (\(E.Value k, E.Value v1, E.Value v2) -> do
            putStrLn $ "BlogKey  => " ++ show(unSqlBackendKey $ unBlogKey k)
            putStrLn $ "    Val1 => " ++ unpack v1
            putStrLn $ "    Val2 => " ++ unpack v2) blogs

esqueletoSay :: IO [(E.Value (Key Blog), E.Value Text, E.Value Text)]
esqueletoSay = runSQLAction $ do
    E.select $ E.from $ \(blog `E.InnerJoin` author) -> do
        E.on $ blog ^. BlogAuthor E.==. author ^. AuthorId
        return ( blog   ^. BlogId
               , blog   ^. BlogTitle
               , author ^. AuthorName )
  
dbInit :: IO ()
dbInit = runSQLAction $ do
          runMigration migrateAll
          p <- selectFirst ([] :: [Filter Author]) []
          case p of
            Nothing -> do
              iid <- insert $ Author "メンチョida(実在しない人物です)" $ Just 40
              insert $ Blog "休みあけ飲みすぎで体調不良です" iid
              insert $ Blog "DriverManagerDataSourceがテストのためだって誰が俺に教えてくれる?" iid
              liftIO $ putStrLn "しょきーか完了..."
            _ -> return ()

runSQLAction :: SqlPersistT (ResourceT (NoLoggingT IO)) a -> IO a
runSQLAction = runNoLoggingT . runResourceT . withMySQLConn getConnection . runSqlConn

getConnection :: ConnectInfo
getConnection = ConnectInfo {
    connectHost = "localhost",
    connectPort = 3306,
    connectUser = "root",
    connectPassword = "",
    connectDatabase = "sampledb",
    connectOptions = [],
    connectPath = "",
    connectSSL = Nothing
}

「えすきゅーぅうれぇっちゅ」を使って複数のテーブル情報を持ってくる方法、実際の値はValueにくるまれてやってくる。
rawなSQLの場合とどう違うのかもうちょっと調べてみようかとおもう。
とりあえず「えすきゅーぅうれぇっちゅ」でした。

だれか読み方教えて...

「えすきゅーぅうれぇっちゅ」セイッ!