refactor: add isParent flag to O2O relationships

It allows to identify the side with the FK when isParent == False
This commit is contained in:
Laurence Isla
2024-05-21 12:11:27 -05:00
committed by GitHub
parent 04d6f41f45
commit 7671d63f06
5 changed files with 33 additions and 32 deletions
+2 -2
View File
@@ -369,7 +369,7 @@ compressedRel Relationship{..} =
"cardinality" .= ("many-to-one" :: Text) "cardinality" .= ("many-to-one" :: Text)
, "relationship" .= (cons <> " using " <> qiName relTable <> fmtEls (fst <$> relColumns) <> " and " <> qiName relForeignTable <> fmtEls (snd <$> relColumns)) , "relationship" .= (cons <> " using " <> qiName relTable <> fmtEls (fst <$> relColumns) <> " and " <> qiName relForeignTable <> fmtEls (snd <$> relColumns))
] ]
O2O cons relColumns -> [ O2O cons relColumns _ -> [
"cardinality" .= ("one-to-one" :: Text) "cardinality" .= ("one-to-one" :: Text)
, "relationship" .= (cons <> " using " <> qiName relTable <> fmtEls (fst <$> relColumns) <> " and " <> qiName relForeignTable <> fmtEls (snd <$> relColumns)) , "relationship" .= (cons <> " using " <> qiName relTable <> fmtEls (fst <$> relColumns) <> " and " <> qiName relForeignTable <> fmtEls (snd <$> relColumns))
] ]
@@ -386,7 +386,7 @@ relHint rels = T.intercalate ", " (hintList <$> rels)
case relCardinality of case relCardinality of
M2M Junction{..} -> buildHint (qiName junTable) M2M Junction{..} -> buildHint (qiName junTable)
M2O cons _ -> buildHint cons M2O cons _ -> buildHint cons
O2O cons _ -> buildHint cons O2O cons _ _ -> buildHint cons
O2M cons _ -> buildHint cons O2M cons _ -> buildHint cons
-- An ambiguousness error cannot happen for computed relationships TODO refactor so this mempty is not needed -- An ambiguousness error cannot happen for computed relationships TODO refactor so this mempty is not needed
hintList ComputedRelationship{} = mempty hintList ComputedRelationship{} = mempty
+11 -11
View File
@@ -508,7 +508,7 @@ getJoinConditions tblAlias parentAlias Relationship{relTable=qi,relForeignTable=
toJoinCondition parentAlias tblAlias tN ftN <$> cols toJoinCondition parentAlias tblAlias tN ftN <$> cols
M2O _ cols -> M2O _ cols ->
toJoinCondition parentAlias tblAlias tN ftN <$> cols toJoinCondition parentAlias tblAlias tN ftN <$> cols
O2O _ cols -> O2O _ cols _ ->
toJoinCondition parentAlias tblAlias tN ftN <$> cols toJoinCondition parentAlias tblAlias tN ftN <$> cols
where where
QualifiedIdentifier{qiSchema=tSchema, qiName=tN} = qi QualifiedIdentifier{qiSchema=tSchema, qiName=tN} = qi
@@ -533,19 +533,19 @@ findRel schema allRels origin target hint =
rs -> Left $ AmbiguousRelBetween origin target rs rs -> Left $ AmbiguousRelBetween origin target rs
where where
matchFKSingleCol hint_ card = case card of matchFKSingleCol hint_ card = case card of
O2M _ [(col, _)] -> hint_ == col O2M{relColumns=[(col, _)]} -> hint_ == col
M2O _ [(col, _)] -> hint_ == col M2O{relColumns=[(col, _)]} -> hint_ == col
O2O _ [(col, _)] -> hint_ == col O2O{relColumns=[(col, _)]} -> hint_ == col
_ -> False _ -> False
matchFKRefSingleCol hint_ card = case card of matchFKRefSingleCol hint_ card = case card of
O2M _ [(_, fCol)] -> hint_ == fCol O2M{relColumns=[(_, fCol)]} -> hint_ == fCol
M2O _ [(_, fCol)] -> hint_ == fCol M2O{relColumns=[(_, fCol)]} -> hint_ == fCol
O2O _ [(_, fCol)] -> hint_ == fCol O2O{relColumns=[(_, fCol)]} -> hint_ == fCol
_ -> False _ -> False
matchConstraint tar card = case card of matchConstraint tar card = case card of
O2M cons _ -> tar == cons O2M{relCons} -> tar == relCons
M2O cons _ -> tar == cons M2O{relCons} -> tar == relCons
O2O cons _ -> tar == cons O2O{relCons} -> tar == relCons
_ -> False _ -> False
matchJunction hint_ card = case card of matchJunction hint_ card = case card of
M2M Junction{junTable} -> hint_ == qiName junTable M2M Junction{junTable} -> hint_ == qiName junTable
@@ -990,7 +990,7 @@ inferColsEmbedNeeds (Node ReadPlan{select} forest) pkCols
Just $ fst <$> cols Just $ fst <$> cols
Node ReadPlan{relToParent=Just Relationship{relCardinality=M2O _ cols}} _ -> Node ReadPlan{relToParent=Just Relationship{relCardinality=M2O _ cols}} _ ->
Just $ fst <$> cols Just $ fst <$> cols
Node ReadPlan{relToParent=Just Relationship{relCardinality=O2O _ cols}} _ -> Node ReadPlan{relToParent=Just Relationship{relCardinality=O2O _ cols _}} _ ->
Just $ fst <$> cols Just $ fst <$> cols
Node ReadPlan{relToParent=Just Relationship{relCardinality=M2M Junction{junColsSource=cols}}} _ -> Node ReadPlan{relToParent=Just Relationship{relCardinality=M2M Junction{junColsSource=cols}}} _ ->
Just $ fst <$> cols Just $ fst <$> cols
+1 -1
View File
@@ -115,7 +115,7 @@ makeProperty tbl rels col = (colName col, Inline s)
-- Finds the relationship that has a single column foreign key -- Finds the relationship that has a single column foreign key
rel = find (\case rel = find (\case
Relationship{relCardinality=(M2O _ relColumns)} -> [colName col] == (fst <$> relColumns) Relationship{relCardinality=(M2O _ relColumns)} -> [colName col] == (fst <$> relColumns)
Relationship{relCardinality=(O2O _ relColumns)} -> [colName col] == (fst <$> relColumns) Relationship{relCardinality=(O2O _ relColumns False)} -> [colName col] == (fst <$> relColumns)
_ -> False _ -> False
) relsSortedByIsView ) relsSortedByIsView
fCol = (headMay . (\r -> snd <$> relColumns (relCardinality r)) =<< rel) fCol = (headMay . (\r -> snd <$> relColumns (relCardinality r)) =<< rel)
+7 -6
View File
@@ -252,7 +252,7 @@ decodeRels :: HD.Result [Relationship]
decodeRels = decodeRels =
HD.rowList relRow HD.rowList relRow
where where
relRow = (\(qi1, qi2, isSelf, constr, cols, isOneToOne) -> Relationship qi1 qi2 isSelf ((if isOneToOne then O2O else M2O) constr cols) False False) <$> row relRow = (\(qi1, qi2, isSelf, constr, cols, isOneToOne)-> Relationship qi1 qi2 isSelf (if isOneToOne then O2O constr cols False else M2O constr cols) False False) <$> row
row = row =
(,,,,,) <$> (,,,,,) <$>
(QualifiedIdentifier <$> column HD.text <*> column HD.text) <*> (QualifiedIdentifier <$> column HD.text <*> column HD.text) <*>
@@ -519,12 +519,13 @@ addViewM2OAndO2ORels keyDeps rels =
rels ++ concatMap viewRels rels rels ++ concatMap viewRels rels
where where
isM2O card = case card of {M2O _ _ -> True; _ -> False;} isM2O card = case card of {M2O _ _ -> True; _ -> False;}
isO2O card = case card of {O2O _ _ -> True; _ -> False;} isO2O card = case card of {O2O _ _ False -> True; _ -> False;}
viewRels Relationship{relTable,relForeignTable,relCardinality=card} = viewRels Relationship{relTable,relForeignTable,relCardinality=card} =
if isM2O card || isO2O card then if isM2O card || isO2O card then
let let
cons = relCons card cons = relCons card
relCols = relColumns card relCols = relColumns card
buildCard cns cls = if isM2O card then M2O cns cls else O2O cns cls False
viewTableRels = filter (\ViewKeyDependency{keyDepTable, keyDepCons, keyDepType} -> keyDepTable == relTable && keyDepCons == cons && keyDepType == FKDep) keyDeps viewTableRels = filter (\ViewKeyDependency{keyDepTable, keyDepCons, keyDepType} -> keyDepTable == relTable && keyDepCons == cons && keyDepType == FKDep) keyDeps
tableViewRels = filter (\ViewKeyDependency{keyDepTable, keyDepCons, keyDepType} -> keyDepTable == relForeignTable && keyDepCons == cons && keyDepType == FKDepRef) keyDeps tableViewRels = filter (\ViewKeyDependency{keyDepTable, keyDepCons, keyDepType} -> keyDepTable == relForeignTable && keyDepCons == cons && keyDepType == FKDepRef) keyDeps
in in
@@ -532,7 +533,7 @@ addViewM2OAndO2ORels keyDeps rels =
(keyDepView vwTbl) (keyDepView vwTbl)
relForeignTable relForeignTable
False False
((if isM2O card then M2O else O2O) cons $ zipWith (\(_, vCol) (_, fCol)-> (vCol, fCol)) keyDepColsVwTbl relCols) (buildCard cons $ zipWith (\(_, vCol) (_, fCol)-> (vCol, fCol)) keyDepColsVwTbl relCols)
True True
False False
| vwTbl <- viewTableRels | vwTbl <- viewTableRels
@@ -542,7 +543,7 @@ addViewM2OAndO2ORels keyDeps rels =
relTable relTable
(keyDepView tblVw) (keyDepView tblVw)
False False
((if isM2O card then M2O else O2O) cons $ zipWith (\(tCol, _) (_, vCol) -> (tCol, vCol)) relCols keyDepColsTblVw) (buildCard cons $ zipWith (\(tCol, _) (_, vCol) -> (tCol, vCol)) relCols keyDepColsTblVw)
False False
True True
| tblVw <- tableViewRels | tblVw <- tableViewRels
@@ -557,7 +558,7 @@ addViewM2OAndO2ORels keyDeps rels =
vw1 vw1
vw2 vw2
(vw1 == vw2) (vw1 == vw2)
((if isM2O card then M2O else O2O) cons $ zipWith (\(_, vcol1) (_, vcol2) -> (vcol1, vcol2)) keyDepColsVwTbl keyDepColsTblVw) (buildCard cons $ zipWith (\(_, vcol1) (_, vcol2) -> (vcol1, vcol2)) keyDepColsVwTbl keyDepColsTblVw)
True True
True True
| vwTbl <- viewTableRels | vwTbl <- viewTableRels
@@ -572,7 +573,7 @@ addInverseRels :: [Relationship] -> [Relationship]
addInverseRels rels = addInverseRels rels =
rels ++ rels ++
[ Relationship ft t isSelf (O2M cons (swap <$> cols)) fTableIsView tableIsView | Relationship t ft isSelf (M2O cons cols) tableIsView fTableIsView <- rels ] ++ [ Relationship ft t isSelf (O2M cons (swap <$> cols)) fTableIsView tableIsView | Relationship t ft isSelf (M2O cons cols) tableIsView fTableIsView <- rels ] ++
[ Relationship ft t isSelf (O2O cons (swap <$> cols)) fTableIsView tableIsView | Relationship t ft isSelf (O2O cons cols) tableIsView fTableIsView <- rels ] [ Relationship ft t isSelf (O2O cons (swap <$> cols) (not isParent)) fTableIsView tableIsView | Relationship t ft isSelf (O2O cons cols isParent) tableIsView fTableIsView <- rels ]
-- | Adds a m2m relationship if a table has FKs to two other tables and the FK columns are part of the PK columns -- | Adds a m2m relationship if a table has FKs to two other tables and the FK columns are part of the PK columns
addM2MRels :: TablesMap -> [Relationship] -> [Relationship] addM2MRels :: TablesMap -> [Relationship] -> [Relationship]
+4 -4
View File
@@ -44,8 +44,8 @@ data Cardinality
-- ^ one-to-many -- ^ one-to-many
| M2O {relCons :: FKConstraint, relColumns :: [(FieldName, FieldName)]} | M2O {relCons :: FKConstraint, relColumns :: [(FieldName, FieldName)]}
-- ^ many-to-one -- ^ many-to-one
| O2O {relCons :: FKConstraint, relColumns :: [(FieldName, FieldName)]} | O2O {relCons :: FKConstraint, relColumns :: [(FieldName, FieldName)], isParent :: Bool}
-- ^ one-to-one, this is a refinement over M2O so operating on it is pretty much the same as M2O -- ^ one-to-one, this is a refinement over M2O, operating on it is pretty much the same as M2O when isParent == False
| M2M Junction | M2M Junction
-- ^ many-to-many -- ^ many-to-many
deriving (Eq, Show, Ord, Generic, JSON.ToJSON) deriving (Eq, Show, Ord, Generic, JSON.ToJSON)
@@ -67,7 +67,7 @@ type RelationshipsMap = HM.HashMap (QualifiedIdentifier, Schema) [Relationship]
relIsToOne :: Relationship -> Bool relIsToOne :: Relationship -> Bool
relIsToOne rel = case rel of relIsToOne rel = case rel of
Relationship{relCardinality=M2O _ _} -> True Relationship{relCardinality=M2O {}} -> True
Relationship{relCardinality=O2O _ _} -> True Relationship{relCardinality=O2O {}} -> True
ComputedRelationship{relToOne=True} -> True ComputedRelationship{relToOne=True} -> True
_ -> False _ -> False