(2017.1 新規作成。)
Webアプリケーションフレームワーク Yesod 用のO/Rマッパ, Persistent を単体で使う。
テーブルごとに別のデータ型になる。ActiveRecord のようなイメージ。
それぞれのテーブルのidフィールドは, SQLまで落ちると単なる整数などになる。そこを, Haskell の世界では別々の型にマッピングすることで, コンパイル時に, 異なるテーブルのidを混ぜたり比較したりできないようにする。
cabal でインストール.
依存関係がとても多い。
Database.Persist.TH
モジュールは別パッケージになっている。persistent-template パッケージ.
バックエンドも別パッケージ。sqlite なら persistent-sqlite パッケージ。
# cabal install --dry-run --global persistent Resolving dependencies... In order, the following would be installed (use -v for more details): auto-update-0.1.4 base-compat-0.9.1 blaze-builder-0.4.0.2 blaze-markup-0.7.1.1 blaze-html-0.8.1.3 bytestring-builder-0.10.8.1.0 dlist-0.8.0.2 easy-file-0.2.1 fail-4.9.0.0 mmorph-1.0.9 monad-loops-0.4.3 path-pieces-0.2.1 semigroups-0.18.2 silently-1.2.5 stm-chans-3.0.0.4 streaming-commons-0.1.16 time-locale-compat-0.1.1.3 transformers-base-0.4.4 monad-control-1.0.1.0 lifted-base-0.2.3.8 resource-pool-0.2.3.2 resourcet-1.1.9 conduit-1.2.8 conduit-extra-1.1.15 unix-time-0.3.7 fast-logger-2.4.7 monad-logger-0.3.20.1 uri-bytestring-0.2.2.1 uuid-types-1.0.3 aeson-1.1.0.0 http-api-data-0.3.3 persistent-2.6
# cabal install --dry-run --global persistent-template Resolving dependencies... In order, the following would be installed (use -v for more details): nats-1.1.1 aeson-compat-0.3.6 persistent-template-2.5.1.6
テーブルを作って, 挿入したり問い合わせたりするサンプル。
テーブル定義ファイルを読み込み, 各テーブルと同名のデータ型を作ります。
Model.hs
ファイル
config/models
ファイル
TemplateHaskell の機能で, User
, BlogPost
というデータ型が宣言される
idというフィールドが自動作成される?
フィールドに使える型は, 型クラス PersistField のインスタンス (拡張可).
SQL | Persistent |
---|---|
データ型 (VARCHAR , INTEGER , etc.)
| PersistValue
|
列 | PersistField
|
表 | PersistEntity
|
これを利用して, データを投入したりする。
Application.hs
ファイル
Database.Persist.insert
の型は, 次のようになっている. idを返す。
Database.Persist.insert :: (Database.Persist.Class.PersistEntity.PersistEntity val, Control.Monad.IO.Class.MonadIO m, Database.Persist.Class.PersistStore.PersistStore (Database.Persist.Class.PersistEntity.PersistEntityBackend val)) => val -> Control.Monad.Trans.Reader.ReaderT (Database.Persist.Class.PersistEntity.PersistEntityBackend val) m (Database.Persist.Class.PersistEntity.Key val)
get
はこう; maybeJohn
は 型 Maybe User
になる。
Database.Persist.get :: (Database.Persist.Class.PersistEntity.PersistEntity val, Control.Monad.IO.Class.MonadIO m, Database.Persist.Class.PersistStore.PersistStore (Database.Persist.Class.PersistEntity.PersistEntityBackend val)) => Database.Persist.Class.PersistEntity.Key val -> Control.Monad.Trans.Reader.ReaderT (Database.Persist.Class.PersistEntity.PersistEntityBackend val) m (Maybe val)
上のサンプルではコメントアウトしているが、挿入に失敗すると, 例外が発生する。TODO: 例外への対処方法.
最後, main
関数.
app/main.hs
ファイル