module Database.Beam.Query.Relationships
(
ManyToMany, ManyToManyThrough
, manyToMany_, manyToManyPassthrough_
, OneToMany, OneToManyOptional
, oneToMany_, oneToManyOptional_
, OneToOne, OneToMaybe
, oneToOne_, oneToMaybe_ ) where
import Database.Beam.Query.Combinators
import Database.Beam.Query.Operator
import Database.Beam.Query.Internal
import Database.Beam.Query.Ord
import Database.Beam.Schema
import Database.Beam.Backend.SQL
type OneToOne be db s one many = OneToMany be db s one many
type OneToMany be db s one many =
( BeamSqlBackend be, BeamSqlBackendCanSerialize be Bool ) =>
one (QExpr be s) -> Q be db s (many (QExpr be s))
type OneToMaybe be db s tbl rel = OneToManyOptional be db s tbl rel
type OneToManyOptional be db s tbl rel =
( BeamSqlBackend be, BeamSqlBackendCanSerialize be Bool
, BeamSqlBackendCanSerialize be SqlNull ) =>
tbl (QExpr be s) -> Q be db s (rel (Nullable (QExpr be s)))
oneToMany_, oneToOne_
:: ( Database be db, BeamSqlBackend be
, HasTableEquality be (PrimaryKey tbl)
, Table tbl, Table rel )
=> DatabaseEntity be db (TableEntity rel)
-> (rel (QExpr be s) -> PrimaryKey tbl (QExpr be s))
-> tbl (QExpr be s)
-> Q be db s (rel (QExpr be s))
oneToMany_ rel getKey tbl =
join_ rel (\rel' -> getKey rel' ==. pk tbl)
oneToOne_ = oneToMany_
oneToManyOptional_, oneToMaybe_
:: ( BeamSqlBackend be, Database be db
, Table tbl, Table rel
, HasTableEqualityNullable be (PrimaryKey tbl) )
=> DatabaseEntity be db (TableEntity rel)
-> (rel (QExpr be s) -> PrimaryKey tbl (Nullable (QExpr be s)))
-> tbl (QExpr be s)
-> Q be db s (rel (Nullable (QExpr be s)))
oneToManyOptional_ rel getKey tbl =
leftJoin_ (all_ rel) (\rel' -> getKey rel' ==. just_ (pk tbl))
oneToMaybe_ = oneToManyOptional_
type ManyToMany be db left right =
forall s.
( BeamSqlBackend be
, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s))
, SqlEq (QExpr be s) (PrimaryKey right (QExpr be s)) ) =>
Q be db s (left (QExpr be s)) -> Q be db s (right (QExpr be s)) ->
Q be db s (left (QExpr be s), right (QExpr be s))
type ManyToManyThrough be db through left right =
forall s.
( BeamSqlBackend be
, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s))
, SqlEq (QExpr be s) (PrimaryKey right (QExpr be s)) ) =>
Q be db s (left (QExpr be s)) -> Q be db s (right (QExpr be s)) ->
Q be db s ( through (QExpr be s), left (QExpr be s), right (QExpr be s) )
manyToMany_
:: ( Database be db
, Table joinThrough, Table left, Table right
, BeamSqlBackend be
, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s))
, SqlEq (QExpr be s) (PrimaryKey right (QExpr be s)) )
=> DatabaseEntity be db (TableEntity joinThrough)
-> (joinThrough (QExpr be s) -> PrimaryKey left (QExpr be s))
-> (joinThrough (QExpr be s) -> PrimaryKey right (QExpr be s))
-> Q be db s (left (QExpr be s)) -> Q be db s (right (QExpr be s))
-> Q be db s (left (QExpr be s), right (QExpr be s))
manyToMany_ joinTbl leftKey rightKey left right = fmap (\(_, l, r) -> (l, r)) $
manyToManyPassthrough_ joinTbl leftKey rightKey left right
manyToManyPassthrough_
:: ( Database be db
, Table joinThrough, Table left, Table right
, BeamSqlBackend be
, SqlEq (QExpr be s) (PrimaryKey left (QExpr be s))
, SqlEq (QExpr be s) (PrimaryKey right (QExpr be s)) )
=> DatabaseEntity be db (TableEntity joinThrough)
-> (joinThrough (QExpr be s) -> PrimaryKey left (QExpr be s))
-> (joinThrough (QExpr be s) -> PrimaryKey right (QExpr be s))
-> Q be db s (left (QExpr be s))
-> Q be db s (right (QExpr be s))
-> Q be db s ( joinThrough (QExpr be s)
, left (QExpr be s)
, right (QExpr be s))
manyToManyPassthrough_ joinTbl leftKey rightKey left right =
do left_ <- left
right_ <- right
joinTbl_ <- join_ joinTbl (\joinTbl_ -> leftKey joinTbl_ ==. primaryKey left_ &&.
rightKey joinTbl_ ==. primaryKey right_)
pure (joinTbl_, left_, right_)