Esqueletoの利用方法(Legacy版)
Type-safeにSQLを扱うためのEDSLでバックエンドはPersistentを利用しているライブラリです。
テーブルのJOIN
from関数 の中で、 InnerJoin や LeftOuterJoin や RightOuterJoin などが利用可能です。
getUsers ::
Param
-> Handler ([(Entity UsrMember, Value Text, 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 = from $ \(usrMember `InnerJoin`
usrImage `InnerJoin`
usrAgeView) -> do
on $ usrMember ^. UsrMemberUsrMemberId ==. usrAgeView ^. UsrAgeViewUid
on $ usrMember ^. UsrMemberUsrMemberId ==. usrImage ^. UsrImageUsrId
where_ $ do
let reqQuery = usrMember ^. UsrMemberReqId ==. val reqId
ageQuery = usrAgeView ^. UsrAgeViewAge >=. val ageFrom
&&. usrAgeView ^. UsrAgeViewAge <=. val ageTo
usrMember ^. UsrMemberTypeId `in_` valList typeIds
&&. (if reqId > 0 then reqQuery else val True)
&&. (if ageFrom > 0 && ageTo > 0 then ageQuery else val True)
&&. usrImage ^. UsrImageImageDiv ==. val 2
return
(
usrMember
, usrImage ^. UsrImageFileName
, usrAgeView ^. UsrAgeViewAge
)
baseQueryPage =
do
r <- baseQuery
offset (pagePerLine * page)
limit pagePerLine
return r
cnt <- Import.length <$> select baseQuery
s <- select baseQueryPage
return (s, cnt)サブクエリ
サブクエリの注意点は、サブクエリの結果が取得できる場合、 subSelect関数 を利用すること、条件によってはサブクエリ結果が取得できない場合は、 subSelectMaybe関数 を利用することです。
getList ::
Key UsrMember
-> Handler Int
getList (UsrMemberKey uid) = runDB $ do
let pagePerLine = 10
page = 0
list <- select $ from $ \(um `InnerJoin` mdt) -> do
let newRec = subSelect $ from $ \mdt -> do
where_ $ mdt ^. MsgDetailRefUsrMemberId ==. um ^. UsrMemberUsrMemberId
limit 1
orderBy [desc (mdt ^. MsgDetailCreateTime)]
return $ mdt ^. MsgDetailCreateTime
on $
um ^. UsrMemberUsrMemberId ==. mdt ^. MsgDetailRefUsrMemberId
where_ $ do
um ^. UsrMemberUsrMemberId ==. val uid
&&.
um ^. UsrMemberStatusFlag >=. val contractStatusFlag
orderBy [ desc (um ^. UsrMemberCreateTime)]
limit pagePerLine
offset page
return (newRec, um ^. UsrMemberNickname)
return 0補足説明
Value typ
select関数 で最後にreturnされる値は、 「um ^. UsrMemberNickname」で、
return (newRec, um ^. UsrMemberNickname)モデルで定義されている、UsrMemberのnicknameのフィールドを意味しています、そしてnicknameフィールドが
UsrMember
...
nickname Text sqltype=varchar(64)
のように宣言されている場合、(Value typ) でtypがText型 (Value Text) で取得できるようになります。
Entity
Entityはテーブル情報そのものを表現しています
return
(
usrMember
, usrImage ^. UsrImageFileName
, usrAgeView ^. UsrAgeViewAge
)usrMemberについては、テーブルすべての項目を取得している書き方で、モデルが
UsrMember
usrMemberId Int sqltype=bigint default=nextval('usr_member_usr_member_id_seq')
...
nickname Text sqltype=varchar(64)のような場合、usrMemberIdは Primary で Auto Increment とすると
data Entity record =
Entity
{
entityKey :: Key record
, entityVal :: record
}で定義されるように、Primary Key と record (実際のレコードデータ) の2つで取得できます。
キーの値を取る場合はパターンマッチで取得するパターンと
func :: Key UsrMember -> Handler ()
func UsrMemberKey pk = do
...Keyを取ってInt64を返す関数として書くこともできます。
fromTblFreeKey :: Key TblFree -> Int64
fromTblFreeKey = unSqlBackendKey . unTblFreeKey備忘録で書いておきます、気がつけば追加していきます。
githubサンプルコード はこちらに置いてあります。
Posted on 2021-01-15 18:06:05
