{-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DataKinds #-} {-# LANGUAGE OverloadedLabels #-} {-# LANGUAGE FlexibleContexts #-} {-# LANGUAGE OverloadedStrings #-} {-# LANGUAGE TypeApplications #-} {-# LANGUAGE TypeOperators #-} {-# LANGUAGE GADTs #-} {-# LANGUAGE DeriveGeneric #-} {-# LANGUAGE DeriveAnyClass #-} {-# LANGUAGE DerivingStrategies #-} module Gauge.Queries where import Squeal.PostgreSQL import GHC.Generics ( Generic ) import qualified Generics.SOP as SOP -- Need below for deriving instances import Control.DeepSeq import Data.Text ( Text ) import Data.Int ( Int16 , Int64 ) import Test.QuickCheck ( Arbitrary(..) ) import Generic.Random ( genericArbitrarySingle ) -- Import Orphan instances import Test.QuickCheck.Instances ( ) -- Project imports import Gauge.Schema -- Types type UserId = Int64 -- Insert user data InsertUser = InsertUser { userEmail :: Text , userPassword :: Text , userFirstName :: Maybe Text , userBirthyear :: Maybe Int16 } deriving (Show, Eq, Generic, NFData) instance SOP.Generic InsertUser instance SOP.HasDatatypeInfo InsertUser -- Arbitrary instances for producing values with quickcheck instance Arbitrary InsertUser where arbitrary = genericArbitrarySingle sampleInsertUser :: InsertUser sampleInsertUser = InsertUser { userEmail = "mark@gmail.com" , userPassword = "MySecretPassword" , userFirstName = Just "Mark" , userBirthyear = Just 1980 } data APIDBUser_ = APIDBUser_ { userId :: UserId , email :: Text , first_name :: Maybe Text , birthyear :: Maybe Int16 } deriving (Show, Eq, Generic, NFData) instance SOP.Generic APIDBUser_ instance SOP.HasDatatypeInfo APIDBUser_ -- Arbitrary instances for producing values with quickcheck instance Arbitrary APIDBUser_ where arbitrary = genericArbitrarySingle data Row3 a b c = Row4 { col1 :: a , col2 :: b , col3 :: c } deriving stock Generic deriving anyclass (SOP.Generic, SOP.HasDatatypeInfo) -- (UserId, Token, OS) type DeviceDetailsRow = Row3 UserId Text (Enumerated DeviceOS) -- -- Queries createUserSession :: InsertUser -> PQ Schemas Schemas IO APIDBUser_ createUserSession insertUser = getRow 0 =<< manipulateParams createUser insertUser createUser :: Manipulation_ Schemas InsertUser APIDBUser_ createUser = insertInto #users (Values_ ( Default `as` #id :* Set (param @1) `as` #email :* Set (param @2) `as` #password :* Set (param @3) `as` #first_name :* Set (param @4 & cast int2) `as` #birthyear ) ) OnConflictDoRaise (Returning_ ( #id `as` #userId :* #email `as` #email :* #first_name `as` #first_name :* #birthyear `as` #birthyear ) ) userDetailsSession :: UserId -> PQ Schemas Schemas IO APIDBUser_ userDetailsSession uID = getRow 0 =<< runQueryParams userDetails (Only uID) userDetails :: Query_ Schemas (Only UserId) APIDBUser_ userDetails = select_ ( #id `as` #userId :* #email `as` #email :* #first_name `as` #first_name :* #birthyear `as` #birthyear ) (from (table #users) & where_ (#id .== (param @1 & cast int8))) insertDeviceDetails :: Manipulation_ Schemas DeviceDetailsRow () insertDeviceDetails = insertInto #user_devices (Values_ ( Default `as` #id :* Set (param @1) `as` #user_id :* Set (param @2) `as` #token :* Set (parameter @3 (typedef #device_os)) `as` #os ) ) OnConflictDoRaise (Returning_ Nil)