Persistent MySQL
自分でpersistent-mysqlのebuildを作っといて放置するのも気が引けたのでテストコードを書いて実際にMySQLに繋いでみた。ほぼYesod本のPersistentのセクションの写経ですが、SQLiteのサンプルがそのままで動かなかったのでチョット修正を加えて試してみました。
自分の環境も問題があると思いますが、その辺はご勘弁を...
イケてるMigration
定義されているデータ型をそのままデータベースにテーブルとして定義(CREATE TABLE)してくれる。ORM的な感じでチョット感動した。作成したテーブルとHaskellのデータ型をマップしてくれる。
サンプルコードはテーブルをMigrationして、そのテーブルへ順次データを挿入していくものです
サンプルコード
{-# LANGUAGE QuasiQuotes, TemplateHaskell, TypeFamilies, OverloadedStrings, GADTs, FlexibleContexts #-}
import Database.Persist
import Database.Persist.MySQL
import Database.Persist.TH
import Control.Monad.Trans.Resource (runResourceT, ResourceT)
share [mkPersist sqlSettings, mkMigrate "migrateAll"] [persistUpperCase|
Person
name String
age Int Maybe
BlogPost
title String
authorId PersonId
|]
main :: IO ()
main = do
registerData
putStrLn "OK Complete!"
registerData :: IO ()
registerData = runResourceT $ getConn $ runSqlConn $ do
runMigration migrateAll
takeId <- insert $ Person "Take Ishii" $ Just 40
asaId <- insert $ Person "Kazu Asaka" $ Just 41
_ <- insert $ BlogPost "今日も酒を飲みすぎました" takeId
_ <- insert $ BlogPost "今日は法事が入っています" asaId
return ()
getConn :: (Connection -> ResourceT IO a) -> ResourceT IO a
getConn = withMySQLConn getConnection
getConnection :: ConnectInfo
getConnection = ConnectInfo {
connectHost = "localhost",
connectPort = 3306,
connectUser = "root",
connectPassword = "",
connectDatabase = "SAMPLEDB",
connectOptions = [],
connectPath = "",
connectSSL = Nothing
}
実行してみる
実行に先立ってMySQLを起動して、SAMPLEDBを作成してください
cuomo@karky7 ~/Code/yesod/Persistent $ mysqladmin -u root create SAMPLEDB
cuomo@karky7 ~/Code/yesod/Persistent $ runhaskell PersistMySQL.hs
Migrating: CREATE TABLE `Person`(`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,`name` TEXT CHARACTER SET utf8 NOT NULL,`age` BIGINT NULL)
Migrating: CREATE TABLE `BlogPost`(`id` BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY,`title` TEXT CHARACTER SET utf8 NOT NULL,`authorId` BIGINT NOT NULL REFERENCES `Person`)
Migrating: ALTER TABLE `BlogPost` ADD CONSTRAINT `BlogPost_authorId_fkey` FOREIGN KEY(`authorId`) REFERENCES `Person`(`id`)
OK Complete!
cuomo@karky7 ~/Code/yesod/Persistent $
cuomo@karky7 ~/Code/yesod/Persistent $ mysql -u root SAMPLEDB
...
...
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql> show tables;
+--------------------+
| Tables_in_SAMPLEDB |
+--------------------+
| BlogPost |
| Person |
+--------------------+
2 rows in set (0.00 sec)
mysql> select * from Person;
+----+------------+------+
| id | name | age |
+----+------------+------+
| 1 | Take Ishii | 40 |
| 2 | Kazu Asaka | 41 |
+----+------------+------+
2 rows in set (0.00 sec)
mysql> select * from BlogPost;
+----+------------------------+----------+
| id | title | authorId |
+----+------------------------+----------+
| 1 | 今日も酒を飲みすぎました | 1 |
| 2 | 今日は法事が入っています | 2 |
+----+------------------------+----------+
2 rows in set (0.00 sec)
こんな感じでデータの挿入が出来る、1テーブル1データ型のマップとなっているのですが、1対多な感じのデータの取得方法や、テーブルJOINなどの場合はどうするのか?
今後の課題です 、では