2013-05-13 10:16:00 +04:00
|
|
|
{-# LANGUAGE MonadComprehensions #-}
|
2013-05-20 02:45:45 +04:00
|
|
|
{-# LANGUAGE FlexibleContexts #-}
|
|
|
|
|
|
|
|
import Database.Record
|
2013-05-13 10:16:00 +04:00
|
|
|
|
|
|
|
import Database.Relational.Query
|
2013-05-20 02:45:45 +04:00
|
|
|
import Database.HDBC (IConnection, SqlValue)
|
2013-05-13 10:16:00 +04:00
|
|
|
|
|
|
|
import qualified User
|
|
|
|
import User (User, user)
|
|
|
|
import qualified Group
|
|
|
|
import Group (Group, group)
|
|
|
|
import Membership (Membership, groupId', userId', membership)
|
|
|
|
|
|
|
|
import PgTestDataSource (connect)
|
|
|
|
import Database.HDBC.Record.Query (runQuery)
|
|
|
|
import Database.HDBC.Session (withConnectionIO)
|
|
|
|
|
2013-05-20 02:45:45 +04:00
|
|
|
|
2013-05-21 05:56:08 +04:00
|
|
|
groupMemberShip :: Relation (Maybe Membership, Group)
|
2013-05-20 02:45:45 +04:00
|
|
|
groupMemberShip =
|
2013-05-21 05:56:08 +04:00
|
|
|
relation $
|
2013-05-21 11:44:17 +04:00
|
|
|
[ m >< g
|
2013-05-20 02:45:45 +04:00
|
|
|
| m <- queryMaybe membership
|
|
|
|
, g <- query group
|
|
|
|
, () <- on $ m !? groupId' .=. just (g ! Group.id')
|
|
|
|
]
|
|
|
|
|
|
|
|
userGroup0 :: Relation (Maybe User, Maybe Group)
|
|
|
|
userGroup0 =
|
|
|
|
relation $
|
2013-05-21 11:44:17 +04:00
|
|
|
[ u >< mg !? snd'
|
2013-05-20 02:45:45 +04:00
|
|
|
| u <- queryMaybe user
|
2013-05-21 05:56:08 +04:00
|
|
|
, mg <- queryMaybe $ nested groupMemberShip
|
2013-05-20 02:45:45 +04:00
|
|
|
-- Call one subquery via relation layer
|
|
|
|
-- Simple implementation.
|
2013-05-21 05:56:08 +04:00
|
|
|
-- Nested SQL. Nested table form joins.
|
2013-05-20 02:45:45 +04:00
|
|
|
|
2013-05-23 09:27:08 +04:00
|
|
|
, () <- on $ u !? User.id' .=. mg !? fst' !?? userId'
|
2013-05-20 02:45:45 +04:00
|
|
|
|
|
|
|
, () <- asc $ u !? User.id'
|
|
|
|
]
|
|
|
|
|
2013-05-21 05:56:08 +04:00
|
|
|
userGroup1 :: Relation (Maybe User, Maybe Group)
|
|
|
|
userGroup1 =
|
|
|
|
relation $
|
2013-05-21 11:44:17 +04:00
|
|
|
[ u >< mg !? snd'
|
2013-05-21 05:56:08 +04:00
|
|
|
| u <- queryMaybe user
|
|
|
|
, mg <- queryMaybe groupMemberShip
|
|
|
|
-- Directly merge another QueryJoin monad.
|
|
|
|
-- Complex implementation.
|
|
|
|
-- Flat SQL. Flat table form joins.
|
2013-05-20 02:45:45 +04:00
|
|
|
|
2013-05-23 09:27:08 +04:00
|
|
|
, () <- on $ u !? User.id' .=. mg !? fst' !?? userId'
|
2013-05-20 02:45:45 +04:00
|
|
|
|
2013-05-21 14:09:34 +04:00
|
|
|
, () <- asc $ u !? User.id'
|
2013-05-21 05:56:08 +04:00
|
|
|
]
|
2013-05-20 02:45:45 +04:00
|
|
|
|
2013-05-21 14:09:34 +04:00
|
|
|
-- userGroup2 :: Relation (Maybe User, Maybe Group)
|
|
|
|
-- userGroup2 =
|
|
|
|
-- relation $
|
|
|
|
-- [ u >< g
|
|
|
|
-- | umg <- query $ (user `left` membership) `full` group
|
|
|
|
-- , let um = umg ! fst'
|
|
|
|
-- u = um !? fst'
|
|
|
|
-- m = flattenMaybe $ um !? snd'
|
|
|
|
-- g = umg ! snd'
|
|
|
|
-- , () <- wheres $ u !? User.id' .=. m !? userId'
|
|
|
|
-- , () <- wheres $ m !? groupId' .=. g !? Group.id'
|
|
|
|
|
|
|
|
-- , () <- asc $ u !? User.id'
|
|
|
|
-- ]
|
|
|
|
|
2013-05-20 02:45:45 +04:00
|
|
|
runAndPrint :: (Show a, IConnection conn, FromSql SqlValue a) => conn -> Relation a -> IO ()
|
|
|
|
runAndPrint conn rel = do
|
2013-05-20 20:22:47 +04:00
|
|
|
putStrLn $ "SQL: " ++ toSQL rel
|
2013-05-20 02:45:45 +04:00
|
|
|
records <- runQuery conn () (fromRelation rel)
|
|
|
|
mapM_ print records
|
|
|
|
putStrLn ""
|
2013-05-13 10:16:00 +04:00
|
|
|
|
|
|
|
run :: IO ()
|
|
|
|
run = withConnectionIO connect
|
|
|
|
(\conn -> do
|
2013-05-20 02:45:45 +04:00
|
|
|
runAndPrint conn userGroup0
|
2013-05-21 05:56:08 +04:00
|
|
|
runAndPrint conn userGroup1
|
2013-05-21 14:09:34 +04:00
|
|
|
-- runAndPrint conn userGroup2
|
2013-05-20 02:45:45 +04:00
|
|
|
)
|
2013-05-13 10:16:00 +04:00
|
|
|
|
|
|
|
main :: IO ()
|
|
|
|
main = run
|