Esqueletoの利用方法(Experimental版)

Tech > Haskell > データベース

Esqueletoのバージョン3系で書き方が二つに分かれた模様

  • Legacy モジュール
  • Experimental モジュール

esqueletoのバージョン3系をインストールした場合、バージョン2系でかかれたコードについては import 文を

import Database.Esqueleto.Legacy

と書き直して古い構文を利用する必要がある。

Experimentalの利用方法

join系の書き方がLegacy版と違っている、Legacy版のjoinは結合先のデータがない場合、Maybeでとらないとランタイム エラーになるケースがあった。

Experimental版の書き方にすることによって、これらがコンパイルの時点で検出できることが利点かなと記憶してる(多分…)

利用方法は、 GHC拡張 を追加

{-# LANGUAGE TypeApplications #-}

TypeApplications拡張 は関数が多態性関数であり、1つ以上の型引数を特定の型にインスタンス化できるようになる拡張です、 @UsrMember のように型を指定することができるようになる。

import宣言をExperimentalで宣言して

import qualified Database.Esqueleto.Experimental

そしてコードを以下のように書く

getUsers :: Param -> HandlerFor App ([(E.Entity UsrMember, E.Value Text, E.Value Int)], Int)
getUsers p = runDB $ do
    let pagePerLine = fromIntegral $ unPagePerLine p
        page = fromIntegral $ unPageNum p
        reqId = fromIntegral $ unReqId p
        typeIds = [1, 2]
        (ageFrom, ageTo) = (unAgeFrom p, unAgeTo p)
        baseQuery = do
          (usrMember E.:& usrImage E.:& usrAgeView) <-
            E.from $ E.table @UsrMember
            `E.InnerJoin` E.table @UsrImage
            `E.on` (\(usrMember E.:& usrImage) ->
                      usrMember E.^. UsrMemberUsrMemberId E.==. usrImage E.^. UsrImageUsrId)
            `E.InnerJoin` E.table @UsrAgeView
            `E.on` (\(usrMember E.:& _ E.:& usrAgeView) ->
                      usrMember E.^. UsrMemberUsrMemberId E.==. usrAgeView E.^. UsrAgeViewUid)
          E.where_ $ do
              let reqQuery = usrMember E.^. UsrMemberReqId E.==. E.val reqId
                  ageQuery = usrAgeView E.^. UsrAgeViewAge E.>=. E.val ageFrom
                                 E.&&. usrAgeView E.^. UsrAgeViewAge E.<=. E.val ageTo
              usrMember E.^. UsrMemberTypeId `E.in_` E.valList typeIds
                  E.&&. (if reqId > 0 then reqQuery else E.val True)
                  E.&&. (if ageFrom > 0 && ageTo > 0 then ageQuery else E.val True)
                  E.&&. usrImage E.^. UsrImageImageDiv E.==. E.val 2
          return (usrMember, usrImage E.^. UsrImageFileName, usrAgeView E.^. UsrAgeViewAge)
        baseQueryPage = do r <- baseQuery; E.offset (pagePerLine * page); E.limit pagePerLine; return r
    cnt <- P.length <$> E.select baseQuery
    s <- E.select baseQueryPage
    return (s,  cnt)

基本的にはさほど変わりませんので、今後はこちらの方が良いと思います。

githubサンプルコード はこちらに置いてあります。

Legacy版 はこちらでございます。

Posted on 2023-11-12 14:58:08

はじめまして

お茶の国静岡で、焼酎のお茶割なんか罰当たりで飲んだことはありません、常に一番搾りを嗜む静岡極東のBBQerです、最近まわりのエンジニアの方々がお料理を上手にやっている姿を恨めしそうに横目に見ながら、軟骨ピリ辛チクワを食べています、みなさんよろしく。

Posted

Amazon

tags

家系 日本酒池 広井酒店 やがら やっぱた 刺身 丸干し 鯵 東京マラソン fpm php82 servant thread spawn Rust Oracle Linux 8 microcode firmware linux openzfs zfs gitea 麒麟 真野鶴 金鶴 日本酒 docker oracle pod podman cli virtualbox VirtualBox epub mobi calibre mask lens ワンライナー php 海 redmine Linux Oracle Map OMap omap map 夏 BBQ カテゴリ管理 カテゴリ timestamp date oracle database string 麦焼酎 ダービー process 磨き蒸留 広井酒店、日本酒 芋焼酎 酒 焼酎 ゆるキャン 広井酒店、日本酒池 spring framework java persistent spring session session spring hdbc-odbc persistent-odbc odbc day utctime スィート レマンの森 elm初期化 elm バイク xlr80 esqueleto database xl2tpd strongswan vpn l2tp ipsec 正月 ゲーム grub nginx systemctl portage 豚骨 圧力鍋 yesod-auth-hashdb yesod-auth