module Database.Relational.Query.Projection (
Projection,
width,
columns,
untype,
unsafeFromSqlTerms,
unsafeFromQualifiedSubQuery,
unsafeFromScalarSubQuery,
unsafeFromTable,
unsafeStringSql,
pi, piMaybe, piMaybe',
wpi,
flattenMaybe, just,
unsafeToAggregated, unsafeToFlat, unsafeChangeContext,
unsafeStringSqlNotNullMaybe,
pfmap, pap,
ListProjection, list, unsafeListFromSubQuery,
unsafeStringSqlList
) where
import Prelude hiding (pi)
import qualified Language.SQL.Keyword as SQL
import Database.Record (HasColumnConstraint, NotNull, NotNullColumnConstraint, PersistableWidth, persistableWidth)
import Database.Record.Persistable (PersistableRecordWidth)
import qualified Database.Record.KeyConstraint as KeyConstraint
import Database.Relational.Query.Internal.SQL (StringSQL, listStringSQL, )
import Database.Relational.Query.Internal.Sub
(SubQuery, Qualified, UntypedProjection,
Projection, untypeProjection, typedProjection, projectionWidth)
import qualified Database.Relational.Query.Internal.Sub as Internal
import Database.Relational.Query.Context (Aggregated, Flat)
import Database.Relational.Query.Table (Table)
import qualified Database.Relational.Query.Table as Table
import Database.Relational.Query.Pure (ProductConstructor (..))
import Database.Relational.Query.Pi (Pi)
import qualified Database.Relational.Query.Pi.Unsafe as UnsafePi
import Database.Relational.Query.Sub
(projectionColumns,
untypedProjectionFromJoinedSubQuery,
unsafeProjectionStringSql)
import qualified Database.Relational.Query.Sub as SubQuery
unsafeStringSql :: Projection c r -> StringSQL
unsafeStringSql = unsafeProjectionStringSql
columns :: Projection c r
-> [StringSQL]
columns = projectionColumns
width :: Projection c r -> Int
width = projectionWidth
untype :: Projection c r -> UntypedProjection
untype = untypeProjection
unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Projection c t
unsafeFromQualifiedSubQuery = typedProjection . untypedProjectionFromJoinedSubQuery
unsafeFromScalarSubQuery :: SubQuery -> Projection c t
unsafeFromScalarSubQuery = Internal.projectFromScalarSubQuery
unsafeFromTable :: Table r
-> Projection c r
unsafeFromTable = Internal.projectFromColumns . Table.columns
unsafeFromSqlTerms :: [StringSQL] -> Projection c t
unsafeFromSqlTerms = Internal.projectFromColumns
unsafeProject :: PersistableRecordWidth a -> Projection c a' -> Pi a b -> Projection c b'
unsafeProject w p pi' =
Internal.projectFromColumns
. (UnsafePi.pi w pi')
. columns $ p
wpi :: PersistableRecordWidth a
-> Projection c a
-> Pi a b
-> Projection c b
wpi = unsafeProject
pi :: PersistableWidth a
=> Projection c a
-> Pi a b
-> Projection c b
pi = unsafeProject persistableWidth
piMaybe :: PersistableWidth a
=> Projection c (Maybe a)
-> Pi a b
-> Projection c (Maybe b)
piMaybe = unsafeProject persistableWidth
piMaybe' :: PersistableWidth a
=> Projection c (Maybe a)
-> Pi a (Maybe b)
-> Projection c (Maybe b)
piMaybe' = unsafeProject persistableWidth
unsafeCast :: Projection c r -> Projection c r'
unsafeCast = typedProjection . untypeProjection
flattenMaybe :: Projection c (Maybe (Maybe a)) -> Projection c (Maybe a)
flattenMaybe = unsafeCast
just :: Projection c r -> Projection c (Maybe r)
just = unsafeCast
unsafeChangeContext :: Projection c r -> Projection c' r
unsafeChangeContext = typedProjection . untypeProjection
unsafeToAggregated :: Projection Flat r -> Projection Aggregated r
unsafeToAggregated = unsafeChangeContext
unsafeToFlat :: Projection Aggregated r -> Projection Flat r
unsafeToFlat = unsafeChangeContext
notNullMaybeConstraint :: HasColumnConstraint NotNull r => Projection c (Maybe r) -> NotNullColumnConstraint r
notNullMaybeConstraint = const KeyConstraint.columnConstraint
unsafeStringSqlNotNullMaybe :: HasColumnConstraint NotNull r => Projection c (Maybe r) -> StringSQL
unsafeStringSqlNotNullMaybe p = (!! KeyConstraint.index (notNullMaybeConstraint p)) . columns $ p
pfmap :: ProductConstructor (a -> b)
=> (a -> b) -> Projection c a -> Projection c b
_ `pfmap` p = unsafeCast p
pap :: Projection c (a -> b) -> Projection c a -> Projection c b
pf `pap` pa = typedProjection $ untypeProjection pf ++ untypeProjection pa
data ListProjection p t = List [p t]
| Sub SubQuery
list :: [p t] -> ListProjection p t
list = List
unsafeListFromSubQuery :: SubQuery -> ListProjection p t
unsafeListFromSubQuery = Sub
unsafeStringSqlList :: (p t -> StringSQL) -> ListProjection p t -> StringSQL
unsafeStringSqlList sf = d where
d (List ps) = listStringSQL $ map sf ps
d (Sub sub) = SQL.paren $ SubQuery.showSQL sub