2013年1月2日水曜日

HaskellのPersistent MySQLを試してみた

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などの場合はどうするのか?

今後の課題です 、では



0 件のコメント:

コメントを投稿