{-# LANGUAGE OverloadedStrings, RecordWildCards, TemplateHaskell, TypeFamilies, FlexibleInstances, UndecidableInstances, MultiParamTypeClasses #-} module Football where import qualified Prelude import Prelude hiding ( (==), (/=), (<), (<=), (>), (>=), (||), (&&), not, sum, minimum, maximum ) import Database.HSQL.MySQL import Database.Squiggle.Types import Database.Squiggle.MySQL import Database.Squiggle.MkInstances c ?? (t,e) = SEPrim SPIfThenElse `SEApp` c `SEApp` t `SEApp` e infix 1 ?? data Result s = Result { r_date :: Apply s Date, r_home :: Apply s String, r_away :: Apply s String, r_homegoals :: Apply s Int, r_awaygoals :: Apply s Int } $(mkInstances ''Result) instance SqlConstr s => HasProdEnc (Result s) where type ProdEnc (Result s) = ProdEncResult s encode = encode . fromResult decode = toResult . decode -- TODO use this once overloading works.. {- points :: Result s -> (Apply s Int, Apply s Int) points Result{..} = r_homegoals > r_awaygoals ?? ((3, 0), r_homegoals == r_awaygoals ?? ((1, 1), (0, 3))) -} data TableLine s = TableLine { tl_club :: Apply s String, tl_points :: Apply s Int, tl_goaldiff :: Apply s Int } $(mkInstances ''TableLine) instance SqlConstr s => HasProdEnc (TableLine s) where type ProdEnc (TableLine s) = ProdEncTableLine s encode = encode . fromTableLine decode = toTableLine . decode homeTableLine :: Result SqlExpr -> TableLine SqlExpr homeTableLine r@Result{..} = TableLine { tl_club = r_home, tl_points = r_homegoals > r_awaygoals ?? (3, r_homegoals == r_awaygoals ?? (1, 0)), tl_goaldiff = r_homegoals - r_awaygoals } awayTableLine :: Result SqlExpr -> TableLine SqlExpr awayTableLine r@Result{..} = TableLine { tl_club = r_away, tl_points = r_homegoals > r_awaygoals ?? (0, r_homegoals == r_awaygoals ?? (1, 3)), tl_goaldiff = r_awaygoals - r_homegoals } results :: Query (Result Id) results = table (Nothing, "results") Result { r_date = field "date", r_home = field "home", r_away = field "away", r_homegoals = field "homegoals", r_awaygoals = field "awaygoals" } leagueTable :: Query (Result Id) -> Query (TableLine Id) leagueTable results = groupBy tl_club (\t -> TableLine { tl_club = the (onAggr tl_club t), tl_points = sum (onAggr tl_points t), tl_goaldiff = sum (onAggr tl_goaldiff t) }) (project homeTableLine results `union` project awayTableLine results) exampleResult :: Query (Result Id) exampleResult = unit $ Result { r_date = date (2008, 01, 01), r_home = "Manchester United", r_away = "Chelsea", r_homegoals = 3, r_awaygoals = 2 }