packages feed

project-m36-1.2.0: examples/Hospital.hs

{-# LANGUAGE DeriveGeneric, DerivingVia, TypeApplications #-}
import ProjectM36.Client
import Data.Typeable
import ProjectM36.Relation
import GHC.Generics
import ProjectM36.Tuple
import System.Random (initStdGen)

-- define a custom data type to use in both the client and database
data AgeType = PreciseAge Int |
               ForgotToAsk |
               RefusedToDisclose |
               NotApplicable |
               ApproximateAge Int Int
               deriving (Eq, Show, Generic)

-- define an automatically-derived Atomable instance
instance Atomable AgeType

failFast :: Show a => IO (Either a b) -> IO b
failFast m = do
  ret <- m
  case ret of
    Left err -> error (show err)
    Right val -> pure val

ageAtomType :: AtomType
ageAtomType = toAtomType (Proxy :: Proxy AgeType)
               
main :: IO ()
main = do
  let bob_relation_attrs = attributesFromList [Attribute "name" TextAtomType,
                                               Attribute "age" ageAtomType]
      relvar_name = "hospital_patient"
      age_value_in = ApproximateAge 30 40 
      mk_bob_relation = mkRelationFromList 
                     bob_relation_attrs 
                     [[TextAtom "Bob",
                       toAtom age_value_in]]

  rando <- initStdGen
  -- create the database
  conn <- failFast $ connectProjectM36 (InProcessConnectionInfo NoPersistence emptyNotificationCallback [] basicDatabaseContext rando "admin")

  -- create the session at the head of master branch
  sessionId <- failFast $ createSessionAtHead conn "master"

  -- create the data type in the database
  failFast $ executeDatabaseContextExpr sessionId conn (toAddTypeExpr (Proxy :: Proxy AgeType))
  
  -- create the patient data in a relation
  bob_relation <- failFast (pure mk_bob_relation)

  -- save the data to the database
  failFast $ executeDatabaseContextExpr sessionId conn (Assign relvar_name (ExistingRelation bob_relation))

  -- retrieve the data from the database
  result <- failFast $ executeRelationalExpr sessionId conn (RelationVariable relvar_name ())

  -- print the data
  case singletonTuple result of
    Nothing -> error "not a singleton relation!"
    Just tuple -> do
      case atomForAttributeName "age" tuple of
        Left err -> error (show err)
        Right age_value_out -> do
          print age_value_in
          print (fromAtom @AgeType age_value_out)