@@ -2,50 +2,35 @@
2{-# LANGUAGE DeriveAnyClass, DeriveGeneric, OverloadedStrings #-}
2{-# LANGUAGE DeriveAnyClass, DeriveGeneric, OverloadedStrings #-}
3import ProjectM36.Client
3import ProjectM36.Client
4import ProjectM36.DataTypes.Primitive
4import ProjectM36.DataTypes.Primitive
5−import qualified Data.Map as M
5+import ProjectM36.Tupleable
6import Data.Either
6import Data.Either
7import Control.Monad
7import Control.Monad
8import GHC.Generics
8import GHC.Generics
9import Data.Binary
9import Data.Binary
10import Control.DeepSeq
10import Control.DeepSeq
11+import qualified Data.Text as T
12+import Data.Time.Calendar (Day)
13+import qualified Data.Vector as V
12--create various database value (atom) types
15--create various database value (atom) types
13−addressAtomType :: AtomType
16+type Price = Double
14−addressAtomType = TextAtomType
16−nameAtomType :: AtomType
18+type Name = T.Text
17−nameAtomType = TextAtomType
19−priceAtomType :: AtomType
20+type Address = T.Text
20−priceAtomType = DoubleAtomType
22−fileNameAtomType :: AtomType
23−fileNameAtomType = TextAtomType
25−data Room = Kitchen | Bathroom | LivingRoom
22+data RoomType = Kitchen | Bathroom | LivingRoom
26 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
23 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
28−roomAtomType :: AtomType
29−roomAtomType = toAtomType (undefined :: Room)
31data PriceBand = Low | Medium | High | Premium
25data PriceBand = Low | Medium | High | Premium
32 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
26 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
34−priceBandAtomType :: AtomType
35−priceBandAtomType = toAtomType (undefined :: PriceBand)
37data AreaCode = City | Suburban | Rural
28data AreaCode = City | Suburban | Rural
38 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
29 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
40−areaCodeAtomType :: AtomType
41−areaCodeAtomType = ConstructedAtomType "AreaCode" M.empty
43data SpeedBand = VeryFastBand | FastBand | MediumBand | SlowBand
31data SpeedBand = VeryFastBand | FastBand | MediumBand | SlowBand
44 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
32 deriving (Generic, Atomable, Eq, Show, Binary, NFData)
46−speedBandAtomType :: AtomType
47−speedBandAtomType = ConstructedAtomType "SpeedBand" M.empty
49main :: IO ()
34main :: IO ()
51 --connect to the database
36 --connect to the database
@@ -62,38 +47,82 @@ main = do
63 createSchema sessionId conn
48 createSchema sessionId conn
54+ deriving (Generic, Eq)
56+instance Tupleable Test
58+data Property = Property {
62+ dateRegistered :: Day
64+ deriving (Generic, Eq)
66+instance Tupleable Property
69+ offerAddress :: Address,
73+ bidderAddress :: Address,
77+ deriving (Generic, Eq)
79+instance Tupleable Offer
81+data Decision = Decision {
82+ dec_address :: Address,
83+ dec_offerDate :: Day, --the dec_ prefix is needed until OverloadedRecordFields is available
84+ dec_bidderName :: Name,
85+ dec_bidderAddress :: Address,
86+ dec_decisionDate :: Day,
89+ deriving (Generic, Eq)
91+instance Tupleable Decision
94+ room_address :: Address,
100+ deriving (Generic, Eq)
102+instance Tupleable Room
105+ floor_address :: Address,
106+ floor_roomName :: Name,
109+ deriving (Generic, Eq)
111+instance Tupleable Floor
113+data Commission = Commission {
114+ priceBand :: PriceBand,
115+ areaCode :: AreaCode,
116+ saleSpeed :: SpeedBand,
118+ } deriving (Generic, Eq)
120+instance Tupleable Commission
65createSchema :: SessionId -> Connection -> IO ()
122createSchema :: SessionId -> Connection -> IO ()
66createSchema sessionId conn = do
123createSchema sessionId conn = do
67 --create attributes for relvars
124 --create attributes for relvars
68− let propertyAttrs = [Attribute "address" addressAtomType,
125+ let
69− Attribute "price" priceAtomType,
70− Attribute "photo" fileNameAtomType,
71− Attribute "dateRegistered" DayAtomType]
72− offerAttrs = [Attribute "address" addressAtomType,
73− Attribute "offerPrice" priceAtomType,
74− Attribute "offerDate" DayAtomType,
75− Attribute "bidderName" nameAtomType,
76− Attribute "bidderAddress" addressAtomType,
77− Attribute "decisionDate" DayAtomType,
78− Attribute "accepted" BoolAtomType]
79− decisionAttrs = [Attribute "address" addressAtomType,
80− Attribute "offerDate" DayAtomType,
81− Attribute "bidderName" nameAtomType,
82− Attribute "bidderAddress" addressAtomType,
83− Attribute "decisionDate" DayAtomType,
84− Attribute "accepted" BoolAtomType]
85− roomAttrs = [Attribute "address" addressAtomType,
86− Attribute "roomName" TextAtomType,
87− Attribute "width" DoubleAtomType,
88− Attribute "breadth" DoubleAtomType,
89− Attribute "type" roomAtomType]
90− floorAttrs = [Attribute "address" addressAtomType,
91− Attribute "roomName" TextAtomType,
92− Attribute "floor" IntAtomType]
93− commissionAttrs = [Attribute "priceBand" priceBandAtomType,
94− Attribute "areaCode" areaCodeAtomType,
95− Attribute "saleSpeed" speedBandAtomType,
96− Attribute "commission" DoubleAtomType]
97 --create uniqueness constraints
126 --create uniqueness constraints
98 incDepKeys = map (uncurry databaseContextExprForUniqueKey)
127 incDepKeys = map (uncurry databaseContextExprForUniqueKey)
99 [("property", ["address"]),
128 [("property", ["address"]),
@@ -120,15 +149,15 @@ createSchema sessionId conn = do
121 incDepForeignKeys = map (\(n, a, b) -> databaseContextExprForForeignKey n a b) foreignKeys
150 incDepForeignKeys = map (\(n, a, b) -> databaseContextExprForForeignKey n a b) foreignKeys
122 --define the relvars
151 --define the relvars
123− relvarMap = [("property", propertyAttrs),
152+ relvarMap = [("property", toAttributes (undefined :: Property)),
124− ("offer", offerAttrs),
153+ ("offer", toAttributes (undefined :: Offer)),
125− ("decision", decisionAttrs),
154+ ("decision", toAttributes (undefined :: Decision)),
126− ("room", roomAttrs),
155+ ("room", toAttributes (undefined :: Room)),
127− ("floor", floorAttrs),
156+ ("floor", toAttributes (undefined :: Floor)),
128− ("commission", commissionAttrs)]
157+ ("commission", toAttributes (undefined :: Commission))]
129− rvDefs = map (\(name, attrs) -> Define name (map NakedAttributeExpr attrs)) relvarMap
158+ rvDefs = map (\(name, typ) -> Define name (map NakedAttributeExpr (V.toList typ))) relvarMap
130 --create the new algebraic data types
159 --create the new algebraic data types
131− new_adts = [toDatabaseContextExpr (undefined :: Room),
160+ new_adts = [toDatabaseContextExpr (undefined :: RoomType),
132 toDatabaseContextExpr (undefined :: PriceBand),
161 toDatabaseContextExpr (undefined :: PriceBand),
133 toDatabaseContextExpr (undefined :: AreaCode),
162 toDatabaseContextExpr (undefined :: AreaCode),
134 toDatabaseContextExpr (undefined :: SpeedBand)]
163 toDatabaseContextExpr (undefined :: SpeedBand)]
@@ -143,8 +172,8 @@ createSchema sessionId conn = do
143 --gather up and execute all database updates
172 --gather up and execute all database updates
144 eErrs <- mapM (executeDatabaseContextExpr sessionId conn) (new_adts ++ rvDefs ++ incDepKeys ++ incDepForeignKeys)
173 eErrs <- mapM (executeDatabaseContextExpr sessionId conn) (new_adts ++ rvDefs ++ incDepKeys ++ incDepForeignKeys)
145 let errs = lefts eErrs
174 let errs = lefts eErrs
146− unless (null errs) (error (show errs))
175+ unless (null errs) (putStrLn (show errs))
148 eErrs' <- mapM (executeDatabaseContextIOExpr sessionId conn) atomFuncs
177 eErrs' <- mapM (executeDatabaseContextIOExpr sessionId conn) atomFuncs
149 let errs' = lefts eErrs'
178 let errs' = lefts eErrs'
150− unless (null errs') (error (show errs'))
179+ unless (null errs') (putStrLn (show errs'))