relational-query 0.9.5.1 → 0.10.0.0
raw patch · 105 files changed
+6427/−6327 lines, 105 filesdep +product-isomorphicdep ~persistable-recordPVP ok
version bump matches the API change (PVP)
Dependencies added: product-isomorphic
Dependency ranges changed: persistable-record
API changes (from Hackage documentation)
- Database.Relational.Query.Arrow: aggregateRelation :: QueryAggregate () (Projection Aggregated r) -> Relation () r
- Database.Relational.Query.Arrow: aggregateRelation' :: QueryAggregate () (PlaceHolders p, Projection Aggregated r) -> Relation p r
- Database.Relational.Query.Arrow: all' :: MonadQuery m => QueryA m () ()
- Database.Relational.Query.Arrow: asc :: Monad m => Orderings c m (Projection c t) ()
- Database.Relational.Query.Arrow: assign :: Monad m => AssignTarget r v -> Assignings r m (Projection Flat v) ()
- Database.Relational.Query.Arrow: bkey :: AggregatingPowerSet (Projection Flat r) (Projection Aggregated (Maybe r))
- Database.Relational.Query.Arrow: cube :: AggregatingPowerSet () a -> AggregateKey a
- Database.Relational.Query.Arrow: data QueryA m a b
- Database.Relational.Query.Arrow: derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p
- Database.Relational.Query.Arrow: derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p
- Database.Relational.Query.Arrow: derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p
- Database.Relational.Query.Arrow: derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p
- Database.Relational.Query.Arrow: derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p
- Database.Relational.Query.Arrow: derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p
- Database.Relational.Query.Arrow: desc :: Monad m => Orderings c m (Projection c t) ()
- Database.Relational.Query.Arrow: distinct :: MonadQuery m => QueryA m () ()
- Database.Relational.Query.Arrow: groupBy :: MonadAggregate m => QueryA m (Projection Flat r) (Projection Aggregated r)
- Database.Relational.Query.Arrow: groupBy' :: MonadAggregate m => QueryA m (AggregateKey (Projection Aggregated r)) (Projection Aggregated r)
- Database.Relational.Query.Arrow: groupingSets :: AggregatingSetList () a -> AggregateKey a
- Database.Relational.Query.Arrow: having :: MonadRestrict Aggregated m => QueryA m (Projection Aggregated (Maybe Bool)) ()
- Database.Relational.Query.Arrow: infix 8 `over`
- Database.Relational.Query.Arrow: instance GHC.Base.Monad m => Control.Arrow.Arrow (Database.Relational.Query.Arrow.QueryA m)
- Database.Relational.Query.Arrow: instance GHC.Base.Monad m => Control.Category.Category (Database.Relational.Query.Arrow.QueryA m)
- Database.Relational.Query.Arrow: key :: AggregatingSet (Projection Flat r) (Projection Aggregated (Maybe r))
- Database.Relational.Query.Arrow: key' :: AggregatingSet (AggregateKey a) a
- Database.Relational.Query.Arrow: on :: MonadQuery m => QueryA m (Projection Flat (Maybe Bool)) ()
- Database.Relational.Query.Arrow: orderBy :: Monad m => Order -> Orderings c m (Projection c t) ()
- Database.Relational.Query.Arrow: orderBy' :: Monad m => Order -> Nulls -> Orderings c m (Projection c t) ()
- Database.Relational.Query.Arrow: over :: SqlProjectable (Projection c) => Projection OverWindow a -> Window c () () -> Projection c a
- Database.Relational.Query.Arrow: partitionBy :: Window c (Projection c r) ()
- Database.Relational.Query.Arrow: placeholder :: (PersistableWidth t, SqlProjectable p, Monad m) => QueryA m (QueryA m (p t) a) (PlaceHolders t, a)
- Database.Relational.Query.Arrow: query :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> QueryA m () (Projection Flat r)
- Database.Relational.Query.Arrow: query' :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation p r -> QueryA m () (PlaceHolders p, Projection Flat r)
- Database.Relational.Query.Arrow: queryExists :: MonadQualify ConfigureQuery m => (Projection c a -> Relation () r) -> QueryA m (Projection c a) (ListProjection (Projection Exists) r)
- Database.Relational.Query.Arrow: queryExists' :: MonadQualify ConfigureQuery m => (Projection c a -> Relation p r) -> QueryA m (Projection c a) (PlaceHolders p, ListProjection (Projection Exists) r)
- Database.Relational.Query.Arrow: queryList :: MonadQualify ConfigureQuery m => (Projection c a -> Relation () r) -> QueryA m (Projection c a) (ListProjection (Projection c) r)
- Database.Relational.Query.Arrow: queryList' :: MonadQualify ConfigureQuery m => (Projection c a -> Relation p r) -> QueryA m (Projection c a) (PlaceHolders p, ListProjection (Projection c) r)
- Database.Relational.Query.Arrow: queryListU :: MonadQualify ConfigureQuery m => Relation () r -> QueryA m () (ListProjection (Projection c) r)
- Database.Relational.Query.Arrow: queryListU' :: MonadQualify ConfigureQuery m => Relation p r -> QueryA m () (PlaceHolders p, ListProjection (Projection c) r)
- Database.Relational.Query.Arrow: queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> QueryA m () (Projection Flat (Maybe r))
- Database.Relational.Query.Arrow: queryMaybe' :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation p r -> QueryA m () (PlaceHolders p, Projection Flat (Maybe r))
- Database.Relational.Query.Arrow: queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r) => (Projection c a -> UniqueRelation () c r) -> QueryA m (Projection c a) (Projection c (Maybe r))
- Database.Relational.Query.Arrow: queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => (Projection c a -> UniqueRelation p c r) -> QueryA m (Projection c a) (PlaceHolders p, Projection c (Maybe r))
- Database.Relational.Query.Arrow: queryScalarU :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation () c r -> QueryA m () (Projection c (Maybe r))
- Database.Relational.Query.Arrow: queryScalarU' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation p c r -> QueryA m () (PlaceHolders p, Projection c (Maybe r))
- Database.Relational.Query.Arrow: relation :: QuerySimple () (Projection Flat r) -> Relation () r
- Database.Relational.Query.Arrow: relation' :: QuerySimple () (PlaceHolders p, Projection Flat r) -> Relation p r
- Database.Relational.Query.Arrow: rollup :: AggregatingPowerSet () a -> AggregateKey a
- Database.Relational.Query.Arrow: set :: AggregatingSetList (AggregatingSet () a) a
- Database.Relational.Query.Arrow: type AggregatingPowerSet = QueryA AggregatingPowerSet
- Database.Relational.Query.Arrow: type AggregatingSet = QueryA AggregatingSet
- Database.Relational.Query.Arrow: type AggregatingSetList = QueryA AggregatingSetList
- Database.Relational.Query.Arrow: type AssignStatement r a = Assignings r Restrict (Projection Flat r) a
- Database.Relational.Query.Arrow: type Assignings r m = QueryA (Assignings r m)
- Database.Relational.Query.Arrow: type Orderings c m = QueryA (Orderings c m)
- Database.Relational.Query.Arrow: type QueryAggregate = QueryA QueryAggregate
- Database.Relational.Query.Arrow: type QuerySimple = QueryA QuerySimple
- Database.Relational.Query.Arrow: type QueryUnique = QueryA QueryUnique
- Database.Relational.Query.Arrow: type Register r a = QueryA (Register r) () a
- Database.Relational.Query.Arrow: type RestrictedStatement r a = QueryA Restrict (Projection Flat r) a
- Database.Relational.Query.Arrow: type Window c = QueryA (Window c)
- Database.Relational.Query.Arrow: uniqueQuery' :: UniqueRelation p c r -> QueryA QueryUnique () (PlaceHolders p, Projection c r)
- Database.Relational.Query.Arrow: uniqueQueryMaybe' :: UniqueRelation p c r -> QueryA QueryUnique () (PlaceHolders p, Projection c (Maybe r))
- Database.Relational.Query.Arrow: uniqueRelation' :: QueryUnique () (PlaceHolders p, Projection c r) -> UniqueRelation p c r
- Database.Relational.Query.Arrow: wheres :: MonadRestrict Flat m => QueryA m (Projection Flat (Maybe Bool)) ()
- Database.Relational.Query.BaseTH: defineProductConstructorInstance :: TypeQ -> ExpQ -> [TypeQ] -> Q [Dec]
- Database.Relational.Query.BaseTH: defineTuplePi :: Int -> Q [Dec]
- Database.Relational.Query.BaseTH: defineTupleProductConstructor :: Int -> Q [Dec]
- Database.Relational.Query.BaseTH: defineTupleShowConstantInstance :: Int -> Q [Dec]
- Database.Relational.Query.Component: Asc :: Order
- Database.Relational.Query.Component: Desc :: Order
- Database.Relational.Query.Component: NameConfig :: NameConfig -> (String -> String -> VarName) -> NameConfig
- Database.Relational.Query.Component: NoQuotation :: IdentifierQuotation
- Database.Relational.Query.Component: NullsFirst :: Nulls
- Database.Relational.Query.Component: NullsLast :: Nulls
- Database.Relational.Query.Component: PUNotSupported :: ProductUnitSupport
- Database.Relational.Query.Component: PUSupported :: ProductUnitSupport
- Database.Relational.Query.Component: Quotation :: Char -> IdentifierQuotation
- Database.Relational.Query.Component: SchemaNotQualified :: SchemaNameMode
- Database.Relational.Query.Component: SchemaQualified :: SchemaNameMode
- Database.Relational.Query.Component: [recordConfig] :: NameConfig -> NameConfig
- Database.Relational.Query.Component: [relationVarName] :: NameConfig -> String -> String -> VarName
- Database.Relational.Query.Component: data AggregateKey a
- Database.Relational.Query.Component: data Config
- Database.Relational.Query.Component: data IdentifierQuotation
- Database.Relational.Query.Component: data NameConfig
- Database.Relational.Query.Component: data Nulls
- Database.Relational.Query.Component: data Order
- Database.Relational.Query.Component: data ProductUnitSupport
- Database.Relational.Query.Component: data SchemaNameMode
- Database.Relational.Query.Component: defaultConfig :: Config
- Database.Relational.Query.Constraint: class PersistableWidth ct => HasConstraintKey c r ct
- Database.Relational.Query.Constraint: constraintKey :: HasConstraintKey c r ct => Key c r ct
- Database.Relational.Query.Constraint: data Key c r ct
- Database.Relational.Query.Constraint: data NotNull :: *
- Database.Relational.Query.Constraint: data Primary :: *
- Database.Relational.Query.Constraint: data Unique :: *
- Database.Relational.Query.Constraint: derivedUniqueKey :: HasConstraintKey Primary r ct => Key Unique r ct
- Database.Relational.Query.Constraint: indexes :: Key c r ct -> [Int]
- Database.Relational.Query.Constraint: projectionKey :: Key c r ct -> Pi r ct
- Database.Relational.Query.Constraint: tableConstraint :: Key c r ct -> KeyConstraint c r
- Database.Relational.Query.Constraint: uniqueKey :: PersistableWidth ct => Key Primary r ct -> Key Unique r ct
- Database.Relational.Query.Constraint: unsafeDefineConstraintKey :: PersistableWidth ct => [Int] -> Key c r ct
- Database.Relational.Query.Context: data Aggregated
- Database.Relational.Query.Context: data Exists
- Database.Relational.Query.Context: data Flat
- Database.Relational.Query.Context: data OverWindow
- Database.Relational.Query.Context: data Power
- Database.Relational.Query.Context: data Set
- Database.Relational.Query.Context: data SetList
- Database.Relational.Query.Derives: derivedUniqueRelation :: TableDerivable r => Key Unique r k -> Projection c k -> UniqueRelation () c r
- Database.Relational.Query.Derives: primary :: HasConstraintKey Primary a p => Relation () a -> Relation p a
- Database.Relational.Query.Derives: primary' :: PersistableWidth p => Key Primary a p -> Relation () a -> Relation p a
- Database.Relational.Query.Derives: primaryUpdate :: (HasConstraintKey Primary r p) => Table r -> KeyUpdate p r
- Database.Relational.Query.Derives: specifiedKey :: PersistableWidth p => Pi a p -> Relation () a -> Relation p a
- Database.Relational.Query.Derives: unique :: PersistableWidth p => Key Unique a p -> Relation () a -> Relation p a
- Database.Relational.Query.Derives: updateByConstraintKey :: Table r -> Key c r p -> KeyUpdate p r
- Database.Relational.Query.Derives: updateValuesWithKey :: ToSql q r => Pi r p -> r -> [q]
- Database.Relational.Query.Effect: data InsertTarget p r
- Database.Relational.Query.Effect: data Restriction p r
- Database.Relational.Query.Effect: data UpdateTarget p r
- Database.Relational.Query.Effect: insertTarget :: Register r () -> InsertTarget () r
- Database.Relational.Query.Effect: insertTarget' :: Register r (PlaceHolders p) -> InsertTarget p r
- Database.Relational.Query.Effect: instance Database.Relational.Query.Table.TableDerivable r => GHC.Show.Show (Database.Relational.Query.Effect.Restriction p r)
- Database.Relational.Query.Effect: instance Database.Relational.Query.Table.TableDerivable r => GHC.Show.Show (Database.Relational.Query.Effect.UpdateTarget p r)
- Database.Relational.Query.Effect: liftTargetAllColumn :: PersistableWidth r => Restriction () r -> UpdateTarget r r
- Database.Relational.Query.Effect: liftTargetAllColumn' :: PersistableWidth r => Restriction p r -> UpdateTarget (r, p) r
- Database.Relational.Query.Effect: piRegister :: PersistableWidth r => Pi r r' -> Register r (PlaceHolders r')
- Database.Relational.Query.Effect: restriction :: RestrictedStatement r () -> Restriction () r
- Database.Relational.Query.Effect: restriction' :: RestrictedStatement r (PlaceHolders p) -> Restriction p r
- Database.Relational.Query.Effect: sqlChunkFromInsertTarget :: Config -> Table r -> InsertTarget p r -> (StringSQL, Int)
- Database.Relational.Query.Effect: sqlFromInsertTarget :: Config -> Table r -> InsertTarget p r -> StringSQL
- Database.Relational.Query.Effect: sqlFromUpdateTarget :: Config -> Table r -> UpdateTarget p r -> StringSQL
- Database.Relational.Query.Effect: sqlWhereFromRestriction :: Config -> Table r -> Restriction p r -> StringSQL
- Database.Relational.Query.Effect: updateTarget :: AssignStatement r () -> UpdateTarget () r
- Database.Relational.Query.Effect: updateTarget' :: AssignStatement r (PlaceHolders p) -> UpdateTarget p r
- Database.Relational.Query.Effect: updateTargetAllColumn :: PersistableWidth r => RestrictedStatement r () -> UpdateTarget r r
- Database.Relational.Query.Effect: updateTargetAllColumn' :: PersistableWidth r => RestrictedStatement r (PlaceHolders p) -> UpdateTarget (r, p) r
- Database.Relational.Query.Monad.Aggregate: infix 8 `over`
- Database.Relational.Query.Monad.Aggregate: instance Database.Relational.Query.Monad.Class.MonadRestrict Database.Relational.Query.Internal.ContextType.Flat q => Database.Relational.Query.Monad.Class.MonadRestrict Database.Relational.Query.Internal.ContextType.Flat (Database.Relational.Query.Monad.Trans.Restricting.Restrictings Database.Relational.Query.Internal.ContextType.Aggregated q)
- Database.Relational.Query.Monad.Aggregate: over :: SqlProjectable (Projection c) => Projection OverWindow a -> Window c () -> Projection c a
- Database.Relational.Query.Monad.Aggregate: toSQL :: AggregatedQuery p r -> ConfigureQuery String
- Database.Relational.Query.Monad.Aggregate: toSubQuery :: AggregatedQuery p r -> ConfigureQuery SubQuery
- Database.Relational.Query.Monad.Aggregate: type AggregatedQuery p r = OrderedQuery Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore)) p r
- Database.Relational.Query.Monad.Aggregate: type QueryAggregate = Orderings Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore))
- Database.Relational.Query.Monad.Aggregate: type Window c = Orderings c (PartitioningSet c)
- Database.Relational.Query.Monad.Assign: extract :: Assign r a -> Config -> ((a, Table r -> [Assignment]), QueryRestriction Flat)
- Database.Relational.Query.Monad.Assign: type Assign r = Assignings r Restrict
- Database.Relational.Query.Monad.Assign: type AssignStatement r a = Projection Flat r -> Assign r a
- Database.Relational.Query.Monad.BaseType: askConfig :: ConfigureQuery Config
- Database.Relational.Query.Monad.BaseType: configureQuery :: ConfigureQuery q -> Config -> q
- Database.Relational.Query.Monad.BaseType: data Relation p r
- Database.Relational.Query.Monad.BaseType: dump :: Relation p r -> String
- Database.Relational.Query.Monad.BaseType: instance GHC.Show.Show (Database.Relational.Query.Monad.BaseType.Relation p r)
- Database.Relational.Query.Monad.BaseType: leftPh :: Relation (p, ()) r -> Relation p r
- Database.Relational.Query.Monad.BaseType: qualifyQuery :: a -> ConfigureQuery (Qualified a)
- Database.Relational.Query.Monad.BaseType: relationWidth :: Relation p r -> PersistableRecordWidth r
- Database.Relational.Query.Monad.BaseType: rightPh :: Relation ((), p) r -> Relation p r
- Database.Relational.Query.Monad.BaseType: sqlFromRelation :: Relation p r -> StringSQL
- Database.Relational.Query.Monad.BaseType: sqlFromRelationWith :: Relation p r -> Config -> StringSQL
- Database.Relational.Query.Monad.BaseType: type ConfigureQuery = Qualify (QueryConfig Identity)
- Database.Relational.Query.Monad.BaseType: unsafeTypeRelation :: ConfigureQuery SubQuery -> Relation p r
- Database.Relational.Query.Monad.BaseType: untypeRelation :: Relation p r -> ConfigureQuery SubQuery
- Database.Relational.Query.Monad.Class: all' :: MonadQuery m => m ()
- Database.Relational.Query.Monad.Class: class MonadQuery m => MonadAggregate m
- Database.Relational.Query.Monad.Class: class Monad m => MonadPartition c m
- Database.Relational.Query.Monad.Class: class (Functor q, Monad q, Functor m, Monad m) => MonadQualify q m
- Database.Relational.Query.Monad.Class: class (Functor m, Monad m, MonadQualify ConfigureQuery m) => MonadQuery m
- Database.Relational.Query.Monad.Class: class (Functor m, Monad m) => MonadRestrict c m
- Database.Relational.Query.Monad.Class: distinct :: MonadQuery m => m ()
- Database.Relational.Query.Monad.Class: groupBy :: MonadAggregate m => Projection Flat r -> m (Projection Aggregated r)
- Database.Relational.Query.Monad.Class: groupBy' :: MonadAggregate m => AggregateKey (Projection Aggregated r) -> m (Projection Aggregated r)
- Database.Relational.Query.Monad.Class: having :: MonadRestrict Aggregated m => Projection Aggregated (Maybe Bool) -> m ()
- Database.Relational.Query.Monad.Class: instance (GHC.Base.Functor q, GHC.Base.Monad q) => Database.Relational.Query.Monad.Class.MonadQualify q q
- Database.Relational.Query.Monad.Class: liftQualify :: MonadQualify q m => q a -> m a
- Database.Relational.Query.Monad.Class: on :: MonadQuery m => Projection Flat (Maybe Bool) -> m ()
- Database.Relational.Query.Monad.Class: partitionBy :: MonadPartition c m => Projection c r -> m ()
- Database.Relational.Query.Monad.Class: query' :: MonadQuery m => Relation p r -> m (PlaceHolders p, Projection Flat r)
- Database.Relational.Query.Monad.Class: queryMaybe' :: MonadQuery m => Relation p r -> m (PlaceHolders p, Projection Flat (Maybe r))
- Database.Relational.Query.Monad.Class: restrict :: MonadRestrict c m => Projection c (Maybe Bool) -> m ()
- Database.Relational.Query.Monad.Class: restrictJoin :: MonadQuery m => Projection Flat (Maybe Bool) -> m ()
- Database.Relational.Query.Monad.Class: setDuplication :: MonadQuery m => Duplication -> m ()
- Database.Relational.Query.Monad.Class: wheres :: MonadRestrict Flat m => Projection Flat (Maybe Bool) -> m ()
- Database.Relational.Query.Monad.Register: extract :: Assignings r ConfigureQuery a -> Config -> (a, Table r -> [Assignment])
- Database.Relational.Query.Monad.Register: type Register r = Assignings r ConfigureQuery
- Database.Relational.Query.Monad.Restrict: extract :: Restrict a -> Config -> (a, QueryRestriction Flat)
- Database.Relational.Query.Monad.Restrict: type Restrict = Restrictings Flat ConfigureQuery
- Database.Relational.Query.Monad.Restrict: type RestrictedStatement r a = Projection Flat r -> Restrict a
- Database.Relational.Query.Monad.Simple: simple :: ConfigureQuery a -> QuerySimple a
- Database.Relational.Query.Monad.Simple: toSQL :: SimpleQuery p r -> ConfigureQuery String
- Database.Relational.Query.Monad.Simple: toSubQuery :: SimpleQuery p r -> ConfigureQuery SubQuery
- Database.Relational.Query.Monad.Simple: type QuerySimple = Orderings Flat QueryCore
- Database.Relational.Query.Monad.Simple: type SimpleQuery p r = OrderedQuery Flat QueryCore p r
- Database.Relational.Query.Monad.Trans.Aggregating: aggregatings :: Monad m => m a -> Aggregatings ac at m a
- Database.Relational.Query.Monad.Trans.Aggregating: bkey :: Projection Flat r -> AggregatingPowerSet (Projection Aggregated (Maybe r))
- Database.Relational.Query.Monad.Trans.Aggregating: cube :: AggregatingPowerSet a -> AggregateKey a
- Database.Relational.Query.Monad.Trans.Aggregating: data Aggregatings ac at m a
- Database.Relational.Query.Monad.Trans.Aggregating: extractAggregateTerms :: (Monad m, Functor m) => Aggregatings ac at m a -> m (a, [at])
- Database.Relational.Query.Monad.Trans.Aggregating: groupingSets :: AggregatingSetList a -> AggregateKey a
- Database.Relational.Query.Monad.Trans.Aggregating: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Query.Monad.Trans.Aggregating.Aggregatings ac at)
- Database.Relational.Query.Monad.Trans.Aggregating: instance Database.Relational.Query.Monad.Class.MonadQualify q m => Database.Relational.Query.Monad.Class.MonadQualify q (Database.Relational.Query.Monad.Trans.Aggregating.AggregatingSetT m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance Database.Relational.Query.Monad.Class.MonadQuery m => Database.Relational.Query.Monad.Class.MonadAggregate (Database.Relational.Query.Monad.Trans.Aggregating.AggregatingSetT m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance Database.Relational.Query.Monad.Class.MonadQuery m => Database.Relational.Query.Monad.Class.MonadQuery (Database.Relational.Query.Monad.Trans.Aggregating.AggregatingSetT m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance Database.Relational.Query.Monad.Class.MonadRestrict c m => Database.Relational.Query.Monad.Class.MonadRestrict c (Database.Relational.Query.Monad.Trans.Aggregating.AggregatingSetT m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Aggregating.Aggregatings ac at m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Aggregating.Aggregatings ac at m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance GHC.Base.Monad m => Database.Relational.Query.Monad.Class.MonadPartition c (Database.Relational.Query.Monad.Trans.Aggregating.PartitioningSetT c m)
- Database.Relational.Query.Monad.Trans.Aggregating: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Aggregating.Aggregatings ac at m)
- Database.Relational.Query.Monad.Trans.Aggregating: key :: Projection Flat r -> AggregatingSet (Projection Aggregated (Maybe r))
- Database.Relational.Query.Monad.Trans.Aggregating: key' :: AggregateKey a -> AggregatingSet a
- Database.Relational.Query.Monad.Trans.Aggregating: rollup :: AggregatingPowerSet a -> AggregateKey a
- Database.Relational.Query.Monad.Trans.Aggregating: set :: AggregatingSet a -> AggregatingSetList a
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingPowerSet = AggregatingPowerSetT Identity
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingPowerSetT = Aggregatings Power AggregateBitKey
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingSet = AggregatingSetT Identity
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingSetList = AggregatingSetListT Identity
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingSetListT = Aggregatings SetList AggregateSet
- Database.Relational.Query.Monad.Trans.Aggregating: type AggregatingSetT = Aggregatings Set AggregateElem
- Database.Relational.Query.Monad.Trans.Aggregating: type PartitioningSet c = PartitioningSetT c Identity
- Database.Relational.Query.Monad.Trans.Aggregating: type PartitioningSetT c = Aggregatings c AggregateColumnRef
- Database.Relational.Query.Monad.Trans.Assigning: (<-#) :: Monad m => AssignTarget r v -> Projection Flat v -> Assignings r m ()
- Database.Relational.Query.Monad.Trans.Assigning: assignTo :: Monad m => Projection Flat v -> AssignTarget r v -> Assignings r m ()
- Database.Relational.Query.Monad.Trans.Assigning: assignings :: Monad m => m a -> Assignings r m a
- Database.Relational.Query.Monad.Trans.Assigning: data Assignings r m a
- Database.Relational.Query.Monad.Trans.Assigning: extractAssignments :: (Monad m, Functor m) => Assignings r m a -> m (a, Table r -> [Assignment])
- Database.Relational.Query.Monad.Trans.Assigning: infix 4 <-#
- Database.Relational.Query.Monad.Trans.Assigning: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Query.Monad.Trans.Assigning.Assignings r)
- Database.Relational.Query.Monad.Trans.Assigning: instance Database.Relational.Query.Monad.Class.MonadQualify q m => Database.Relational.Query.Monad.Class.MonadQualify q (Database.Relational.Query.Monad.Trans.Assigning.Assignings r m)
- Database.Relational.Query.Monad.Trans.Assigning: instance Database.Relational.Query.Monad.Class.MonadRestrict c m => Database.Relational.Query.Monad.Class.MonadRestrict c (Database.Relational.Query.Monad.Trans.Assigning.Assignings r m)
- Database.Relational.Query.Monad.Trans.Assigning: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Assigning.Assignings r m)
- Database.Relational.Query.Monad.Trans.Assigning: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Assigning.Assignings r m)
- Database.Relational.Query.Monad.Trans.Assigning: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Assigning.Assignings r m)
- Database.Relational.Query.Monad.Trans.Assigning: type AssignTarget r v = Pi r v
- Database.Relational.Query.Monad.Trans.Config: askQueryConfig :: Monad m => QueryConfig m Config
- Database.Relational.Query.Monad.Trans.Config: data QueryConfig m a
- Database.Relational.Query.Monad.Trans.Config: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Config.QueryConfig m)
- Database.Relational.Query.Monad.Trans.Config: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Config.QueryConfig m)
- Database.Relational.Query.Monad.Trans.Config: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Config.QueryConfig m)
- Database.Relational.Query.Monad.Trans.Config: queryConfig :: Monad m => m a -> QueryConfig m a
- Database.Relational.Query.Monad.Trans.Config: runQueryConfig :: QueryConfig m a -> Config -> m a
- Database.Relational.Query.Monad.Trans.Join: data QueryJoin m a
- Database.Relational.Query.Monad.Trans.Join: extractProduct :: Functor m => QueryJoin m a -> m ((a, JoinProduct), Duplication)
- Database.Relational.Query.Monad.Trans.Join: instance Control.Monad.Trans.Class.MonadTrans Database.Relational.Query.Monad.Trans.Join.QueryJoin
- Database.Relational.Query.Monad.Trans.Join: instance Database.Relational.Query.Monad.Class.MonadQualify q m => Database.Relational.Query.Monad.Class.MonadQualify q (Database.Relational.Query.Monad.Trans.Join.QueryJoin m)
- Database.Relational.Query.Monad.Trans.Join: instance Database.Relational.Query.Monad.Class.MonadQuery (Database.Relational.Query.Monad.Trans.Join.QueryJoin Database.Relational.Query.Monad.BaseType.ConfigureQuery)
- Database.Relational.Query.Monad.Trans.Join: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Join.QueryJoin m)
- Database.Relational.Query.Monad.Trans.Join: instance GHC.Base.Monad m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Join.QueryJoin m)
- Database.Relational.Query.Monad.Trans.Join: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Join.QueryJoin m)
- Database.Relational.Query.Monad.Trans.Join: join' :: Monad m => m a -> QueryJoin m a
- Database.Relational.Query.Monad.Trans.Join: unsafeSubQueryWithAttr :: Monad q => NodeAttr -> Qualified SubQuery -> QueryJoin q (Projection c r)
- Database.Relational.Query.Monad.Trans.Ordering: asc :: (Monad m, ProjectableOrdering (Projection c)) => Projection c t -> Orderings c m ()
- Database.Relational.Query.Monad.Trans.Ordering: data Orderings c m a
- Database.Relational.Query.Monad.Trans.Ordering: desc :: (Monad m, ProjectableOrdering (Projection c)) => Projection c t -> Orderings c m ()
- Database.Relational.Query.Monad.Trans.Ordering: extractOrderingTerms :: (Monad m, Functor m) => Orderings c m a -> m (a, [OrderingTerm])
- Database.Relational.Query.Monad.Trans.Ordering: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Query.Monad.Trans.Ordering.Orderings c)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Class.MonadAggregate m => Database.Relational.Query.Monad.Class.MonadAggregate (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Class.MonadPartition c m => Database.Relational.Query.Monad.Class.MonadPartition c (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Class.MonadQualify q m => Database.Relational.Query.Monad.Class.MonadQualify q (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Class.MonadQuery m => Database.Relational.Query.Monad.Class.MonadQuery (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Class.MonadRestrict rc m => Database.Relational.Query.Monad.Class.MonadRestrict rc (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance Database.Relational.Query.Monad.Trans.Ordering.ProjectableOrdering (Database.Relational.Query.Internal.Sub.Projection c)
- Database.Relational.Query.Monad.Trans.Ordering: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Ordering.Orderings c m)
- Database.Relational.Query.Monad.Trans.Ordering: orderBy :: (Monad m, ProjectableOrdering (Projection c)) => Projection c t -> Order -> Orderings c m ()
- Database.Relational.Query.Monad.Trans.Ordering: orderBy' :: (Monad m, ProjectableOrdering (Projection c)) => Projection c t -> Order -> Nulls -> Orderings c m ()
- Database.Relational.Query.Monad.Trans.Ordering: orderings :: Monad m => m a -> Orderings c m a
- Database.Relational.Query.Monad.Trans.Restricting: data Restrictings c m a
- Database.Relational.Query.Monad.Trans.Restricting: extractRestrict :: (Monad m, Functor m) => Restrictings c m a -> m (a, QueryRestriction c)
- Database.Relational.Query.Monad.Trans.Restricting: instance (GHC.Base.Monad q, GHC.Base.Functor q) => Database.Relational.Query.Monad.Class.MonadRestrict c (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c q)
- Database.Relational.Query.Monad.Trans.Restricting: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c)
- Database.Relational.Query.Monad.Trans.Restricting: instance Database.Relational.Query.Monad.Class.MonadAggregate m => Database.Relational.Query.Monad.Class.MonadAggregate (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c m)
- Database.Relational.Query.Monad.Trans.Restricting: instance Database.Relational.Query.Monad.Class.MonadQualify q m => Database.Relational.Query.Monad.Class.MonadQualify q (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c m)
- Database.Relational.Query.Monad.Trans.Restricting: instance Database.Relational.Query.Monad.Class.MonadQuery q => Database.Relational.Query.Monad.Class.MonadQuery (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c q)
- Database.Relational.Query.Monad.Trans.Restricting: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c m)
- Database.Relational.Query.Monad.Trans.Restricting: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c m)
- Database.Relational.Query.Monad.Trans.Restricting: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Query.Monad.Trans.Restricting.Restrictings c m)
- Database.Relational.Query.Monad.Trans.Restricting: restrictings :: Monad m => m a -> Restrictings c m a
- Database.Relational.Query.Monad.Type: extractCore :: QueryCore a -> ConfigureQuery (((a, QueryRestriction Flat), JoinProduct), Duplication)
- Database.Relational.Query.Monad.Type: type OrderedQuery c m p r = Orderings c m (PlaceHolders p, Projection c r)
- Database.Relational.Query.Monad.Type: type QueryCore = Restrictings Flat (QueryJoin ConfigureQuery)
- Database.Relational.Query.Monad.Unique: data QueryUnique a
- Database.Relational.Query.Monad.Unique: instance Database.Relational.Query.Monad.Class.MonadQualify Database.Relational.Query.Monad.BaseType.ConfigureQuery Database.Relational.Query.Monad.Unique.QueryUnique
- Database.Relational.Query.Monad.Unique: instance Database.Relational.Query.Monad.Class.MonadQuery Database.Relational.Query.Monad.Unique.QueryUnique
- Database.Relational.Query.Monad.Unique: instance GHC.Base.Applicative Database.Relational.Query.Monad.Unique.QueryUnique
- Database.Relational.Query.Monad.Unique: instance GHC.Base.Functor Database.Relational.Query.Monad.Unique.QueryUnique
- Database.Relational.Query.Monad.Unique: instance GHC.Base.Monad Database.Relational.Query.Monad.Unique.QueryUnique
- Database.Relational.Query.Monad.Unique: toSubQuery :: QueryUnique (PlaceHolders p, Projection c r) -> ConfigureQuery SubQuery
- Database.Relational.Query.Monad.Unique: unsafeUniqueSubQuery :: NodeAttr -> Qualified SubQuery -> QueryUnique (Projection c r)
- Database.Relational.Query.Pi: (<.>) :: Pi a b -> Pi b c -> Pi a c
- Database.Relational.Query.Pi: (<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)
- Database.Relational.Query.Pi: (<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)
- Database.Relational.Query.Pi: data Pi r0 r1
- Database.Relational.Query.Pi: fst' :: PersistableWidth a => Pi (a, b) a
- Database.Relational.Query.Pi: id' :: Pi a a
- Database.Relational.Query.Pi: infixl 8 <?.?>
- Database.Relational.Query.Pi: pap :: Pi r (a -> b) -> Pi r a -> Pi r b
- Database.Relational.Query.Pi: pfmap :: ProductConstructor (a -> b) => (a -> b) -> Pi r a -> Pi r b
- Database.Relational.Query.Pi: pzero :: Pi a ()
- Database.Relational.Query.Pi: snd' :: (PersistableWidth a, PersistableWidth b) => Pi (a, b) b
- Database.Relational.Query.Pi.Unsafe: (<.>) :: Pi a b -> Pi b c -> Pi a c
- Database.Relational.Query.Pi.Unsafe: (<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)
- Database.Relational.Query.Pi.Unsafe: (<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)
- Database.Relational.Query.Pi.Unsafe: data Pi r0 r1
- Database.Relational.Query.Pi.Unsafe: defineDirectPi :: PersistableWidth r1 => [Int] -> Pi r0 r1
- Database.Relational.Query.Pi.Unsafe: defineDirectPi' :: PersistableRecordWidth r1 -> [Int] -> Pi r0 r1
- Database.Relational.Query.Pi.Unsafe: definePi :: PersistableWidth r1 => Int -> Pi r0 r1
- Database.Relational.Query.Pi.Unsafe: infixl 8 <?.?>
- Database.Relational.Query.Pi.Unsafe: instance Control.Category.Category Database.Relational.Query.Pi.Unsafe.Pi
- Database.Relational.Query.Pi.Unsafe: instance Database.Record.Persistable.PersistableWidth r0 => GHC.Show.Show (Database.Relational.Query.Pi.Unsafe.Pi r0 r1)
- Database.Relational.Query.Pi.Unsafe: instance Database.Relational.Query.ProjectableClass.ProjectableApplicative (Database.Relational.Query.Pi.Unsafe.Pi a)
- Database.Relational.Query.Pi.Unsafe: instance Database.Relational.Query.ProjectableClass.ProjectableFunctor (Database.Relational.Query.Pi.Unsafe.Pi a)
- Database.Relational.Query.Pi.Unsafe: pap :: Pi r (a -> b) -> Pi r a -> Pi r b
- Database.Relational.Query.Pi.Unsafe: pfmap :: ProductConstructor (a -> b) => (a -> b) -> Pi r a -> Pi r b
- Database.Relational.Query.Pi.Unsafe: pi :: PersistableRecordWidth r0 -> Pi r0 r1 -> [a] -> [a]
- Database.Relational.Query.Pi.Unsafe: pzero :: Pi a ()
- Database.Relational.Query.Pi.Unsafe: unsafeExpandIndexes :: PersistableWidth a => Pi a b -> [Int]
- Database.Relational.Query.Pi.Unsafe: unsafeExpandIndexes' :: PersistableRecordWidth a -> Pi a b -> [Int]
- Database.Relational.Query.Pi.Unsafe: width :: PersistableWidth r => Pi r a -> Int
- Database.Relational.Query.Pi.Unsafe: width' :: PersistableWidth r => Pi r ct -> PersistableRecordWidth ct
- Database.Relational.Query.Projectable: (.*.) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p a -> p a -> p a
- Database.Relational.Query.Projectable: (.+.) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p a -> p a -> p a
- Database.Relational.Query.Projectable: (.-.) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p a -> p a -> p a
- Database.Relational.Query.Projectable: (./.) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p a -> p a -> p a
- Database.Relational.Query.Projectable: (.<.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.<=.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.<>.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.=.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.>.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.>=.) :: (OperatorProjectable p, ProjectableShowSql p) => p ft -> p ft -> p (Maybe Bool)
- Database.Relational.Query.Projectable: (.||.) :: (OperatorProjectable p, ProjectableShowSql p, IsString a) => p a -> p a -> p a
- Database.Relational.Query.Projectable: (><) :: ProjectableApplicative p => p a -> p b -> p (a, b)
- Database.Relational.Query.Projectable: (?*?) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p (Maybe a) -> p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: (?+?) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p (Maybe a) -> p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: (?-?) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p (Maybe a) -> p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: (?/?) :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p (Maybe a) -> p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: (?||?) :: (OperatorProjectable p, ProjectableShowSql p, IsString a) => p (Maybe a) -> p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: and' :: (OperatorProjectable p, ProjectableShowSql p) => p (Maybe Bool) -> p (Maybe Bool) -> p (Maybe Bool)
- Database.Relational.Query.Projectable: case' :: OperatorProjectable (Projection c) => Projection c a -> [(Projection c a, Projection c b)] -> Projection c b -> Projection c b
- Database.Relational.Query.Projectable: caseMaybe :: (OperatorProjectable (Projection c), PersistableWidth b) => Projection c a -> [(Projection c a, Projection c (Maybe b))] -> Projection c (Maybe b)
- Database.Relational.Query.Projectable: caseSearch :: OperatorProjectable (Projection c) => [(Projection c (Maybe Bool), Projection c a)] -> Projection c a -> Projection c a
- Database.Relational.Query.Projectable: caseSearchMaybe :: (OperatorProjectable (Projection c), PersistableWidth a) => [(Projection c (Maybe Bool), Projection c (Maybe a))] -> Projection c (Maybe a)
- Database.Relational.Query.Projectable: casesOrElse :: OperatorProjectable (Projection c) => [(Projection c (Maybe Bool), Projection c a)] -> Projection c a -> Projection c a
- Database.Relational.Query.Projectable: casesOrElse' :: OperatorProjectable (Projection c) => (Projection c a, [(Projection c a, Projection c b)]) -> Projection c b -> Projection c b
- Database.Relational.Query.Projectable: class ProjectableApplicative p => ProjectableIdZip p
- Database.Relational.Query.Projectable: class ProjectableMaybe p
- Database.Relational.Query.Projectable: class ProjectableShowSql p
- Database.Relational.Query.Projectable: class SqlProjectable p
- Database.Relational.Query.Projectable: cumeDist :: Projection OverWindow Double
- Database.Relational.Query.Projectable: data PlaceHolders p
- Database.Relational.Query.Projectable: denseRank :: Integral a => Projection OverWindow a
- Database.Relational.Query.Projectable: exists :: (OperatorProjectable p, ProjectableShowSql p) => ListProjection (Projection Exists) r -> p (Maybe Bool)
- Database.Relational.Query.Projectable: flattenMaybe :: ProjectableMaybe p => p (Maybe (Maybe a)) -> p (Maybe a)
- Database.Relational.Query.Projectable: fromIntegral' :: (SqlProjectable p, ProjectableShowSql p, Integral a, Num b) => p a -> p b
- Database.Relational.Query.Projectable: fromIntegralMaybe :: (SqlProjectable p, ProjectableShowSql p, Integral a, Num b) => p (Maybe a) -> p (Maybe b)
- Database.Relational.Query.Projectable: fromMaybe :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r) => Projection c r -> Projection c (Maybe r) -> Projection c r
- Database.Relational.Query.Projectable: in' :: (OperatorProjectable p, ProjectableShowSql p) => p t -> ListProjection p t -> p (Maybe Bool)
- Database.Relational.Query.Projectable: infix 4 `likeMaybe'`
- Database.Relational.Query.Projectable: infixl 1 ><
- Database.Relational.Query.Projectable: infixl 5 ?||?
- Database.Relational.Query.Projectable: infixl 6 ?-?
- Database.Relational.Query.Projectable: infixl 7 ?/?
- Database.Relational.Query.Projectable: infixr 2 `or'`
- Database.Relational.Query.Projectable: infixr 3 `and'`
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.OperatorProjectable (Database.Relational.Query.Internal.Sub.Projection Database.Relational.Query.Internal.ContextType.Aggregated)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.OperatorProjectable (Database.Relational.Query.Internal.Sub.Projection Database.Relational.Query.Internal.ContextType.Flat)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.ProjectableIdZip Database.Relational.Query.Projectable.PlaceHolders
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.ProjectableMaybe (Database.Relational.Query.Internal.Sub.Projection c)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.ProjectableMaybe Database.Relational.Query.Projectable.PlaceHolders
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.ProjectableShowSql (Database.Relational.Query.Internal.Sub.Projection c)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.SqlProjectable (Database.Relational.Query.Internal.Sub.Projection Database.Relational.Query.Internal.ContextType.Aggregated)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.SqlProjectable (Database.Relational.Query.Internal.Sub.Projection Database.Relational.Query.Internal.ContextType.Flat)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.Projectable.SqlProjectable (Database.Relational.Query.Internal.Sub.Projection Database.Relational.Query.Internal.ContextType.OverWindow)
- Database.Relational.Query.Projectable: instance Database.Relational.Query.ProjectableClass.ProjectableApplicative Database.Relational.Query.Projectable.PlaceHolders
- Database.Relational.Query.Projectable: instance Database.Relational.Query.ProjectableClass.ProjectableFunctor Database.Relational.Query.Projectable.PlaceHolders
- Database.Relational.Query.Projectable: isJust :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r) => Projection c (Maybe r) -> Projection c (Maybe Bool)
- Database.Relational.Query.Projectable: isNothing :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r) => Projection c (Maybe r) -> Projection c (Maybe Bool)
- Database.Relational.Query.Projectable: just :: ProjectableMaybe p => p a -> p (Maybe a)
- Database.Relational.Query.Projectable: leftId :: ProjectableIdZip p => p ((), a) -> p a
- Database.Relational.Query.Projectable: like :: (OperatorProjectable p, ProjectableShowSql p, IsString a, ShowConstantTermsSQL a) => p a -> a -> p (Maybe Bool)
- Database.Relational.Query.Projectable: like' :: (OperatorProjectable p, ProjectableShowSql p, IsString a) => p a -> p a -> p (Maybe Bool)
- Database.Relational.Query.Projectable: likeMaybe :: (OperatorProjectable p, ProjectableShowSql p, IsString a, ShowConstantTermsSQL a) => p (Maybe a) -> a -> p (Maybe Bool)
- Database.Relational.Query.Projectable: likeMaybe' :: (OperatorProjectable p, ProjectableShowSql p, IsString a) => p (Maybe a) -> p (Maybe a) -> p (Maybe Bool)
- Database.Relational.Query.Projectable: negate' :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p a -> p a
- Database.Relational.Query.Projectable: negateMaybe :: (OperatorProjectable p, ProjectableShowSql p, Num a) => p (Maybe a) -> p (Maybe a)
- Database.Relational.Query.Projectable: not' :: (OperatorProjectable p, ProjectableShowSql p) => p (Maybe Bool) -> p (Maybe Bool)
- Database.Relational.Query.Projectable: nothing :: (OperatorProjectable (Projection c), SqlProjectable (Projection c), PersistableWidth a) => Projection c (Maybe a)
- Database.Relational.Query.Projectable: or' :: (OperatorProjectable p, ProjectableShowSql p) => p (Maybe Bool) -> p (Maybe Bool) -> p (Maybe Bool)
- Database.Relational.Query.Projectable: percentRank :: Projection OverWindow Double
- Database.Relational.Query.Projectable: placeholder :: (PersistableWidth t, SqlProjectable p, Monad m) => (p t -> m a) -> m (PlaceHolders t, a)
- Database.Relational.Query.Projectable: placeholder' :: (PersistableWidth t, SqlProjectable p) => (p t -> a) -> (PlaceHolders t, a)
- Database.Relational.Query.Projectable: projectZip :: ProjectableApplicative p => p a -> p b -> p (a, b)
- Database.Relational.Query.Projectable: pwPlaceholder :: SqlProjectable p => PersistableRecordWidth a -> (p a -> b) -> (PlaceHolders a, b)
- Database.Relational.Query.Projectable: rank :: Integral a => Projection OverWindow a
- Database.Relational.Query.Projectable: rightId :: ProjectableIdZip p => p (a, ()) -> p a
- Database.Relational.Query.Projectable: rowNumber :: Integral a => Projection OverWindow a
- Database.Relational.Query.Projectable: showNum :: (SqlProjectable p, ProjectableShowSql p, Num a, IsString b) => p a -> p b
- Database.Relational.Query.Projectable: showNumMaybe :: (SqlProjectable p, ProjectableShowSql p, Num a, IsString b) => p (Maybe a) -> p (Maybe b)
- Database.Relational.Query.Projectable: type SqlBinOp = Keyword -> Keyword -> Keyword
- Database.Relational.Query.Projectable: unitPH :: PlaceHolders ()
- Database.Relational.Query.Projectable: unitPlaceHolder :: PlaceHolders ()
- Database.Relational.Query.Projectable: unsafeAddPlaceHolders :: Functor f => f a -> f (PlaceHolders p, a)
- Database.Relational.Query.Projectable: unsafeBinOp :: (SqlProjectable p, ProjectableShowSql p) => SqlBinOp -> p a -> p b -> p c
- Database.Relational.Query.Projectable: unsafePlaceHolders :: PlaceHolders p
- Database.Relational.Query.Projectable: unsafeProjectSql :: SqlProjectable p => String -> p t
- Database.Relational.Query.Projectable: unsafeProjectSql' :: SqlProjectable p => StringSQL -> p t
- Database.Relational.Query.Projectable: unsafeProjectSqlTerms :: SqlProjectable p => [StringSQL] -> p t
- Database.Relational.Query.Projectable: unsafeShowSql :: ProjectableShowSql p => p a -> String
- Database.Relational.Query.Projectable: unsafeShowSql' :: ProjectableShowSql p => p a -> StringSQL
- Database.Relational.Query.Projectable: unsafeUniOp :: (ProjectableShowSql p0, SqlProjectable p1) => (Keyword -> Keyword) -> p0 a -> p1 b
- Database.Relational.Query.Projectable: unsafeValueNull :: (OperatorProjectable (Projection c), SqlProjectable (Projection c), PersistableWidth a) => Projection c (Maybe a)
- Database.Relational.Query.Projectable: value :: (ShowConstantTermsSQL t, OperatorProjectable p) => t -> p t
- Database.Relational.Query.Projectable: valueFalse :: (OperatorProjectable p, ProjectableMaybe p) => p (Maybe Bool)
- Database.Relational.Query.Projectable: valueTrue :: (OperatorProjectable p, ProjectableMaybe p) => p (Maybe Bool)
- Database.Relational.Query.Projectable: values :: (ShowConstantTermsSQL t, OperatorProjectable p) => [t] -> ListProjection p t
- Database.Relational.Query.ProjectableClass: (|$|) :: (ProjectableFunctor p, ProductConstructor (a -> b)) => (a -> b) -> p a -> p b
- Database.Relational.Query.ProjectableClass: (|*|) :: ProjectableApplicative p => p (a -> b) -> p a -> p b
- Database.Relational.Query.ProjectableClass: class ProductConstructor r
- Database.Relational.Query.ProjectableClass: class ProjectableFunctor p => ProjectableApplicative p
- Database.Relational.Query.ProjectableClass: class ProjectableFunctor p
- Database.Relational.Query.ProjectableClass: class ShowConstantTermsSQL a where showConstantTermsSQL' = gShowConstantTermsSQL . from
- Database.Relational.Query.ProjectableClass: instance (Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL a, Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL b) => Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL (a GHC.Generics.:*: b)
- Database.Relational.Query.ProjectableClass: instance Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL GHC.Generics.U1
- Database.Relational.Query.ProjectableClass: instance Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL a => Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL (GHC.Generics.M1 i c a)
- Database.Relational.Query.ProjectableClass: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a => Database.Relational.Query.ProjectableClass.GShowConstantTermsSQL (GHC.Generics.K1 i a)
- Database.Relational.Query.ProjectableClass: ipfmap :: (ProjectableFunctor p, ProductConstructor (a -> b)) => p a -> p b
- Database.Relational.Query.ProjectableClass: productConstructor :: ProductConstructor r => r
- Database.Relational.Query.ProjectableClass: showConstantTermsSQL :: ShowConstantTermsSQL a => a -> [StringSQL]
- Database.Relational.Query.ProjectableClass: showConstantTermsSQL' :: (ShowConstantTermsSQL a, Generic a, GShowConstantTermsSQL (Rep a)) => a -> DList StringSQL
- Database.Relational.Query.ProjectableClass: type StringSQL = Keyword
- Database.Relational.Query.ProjectableExtended: (!) :: PersistableWidth a => Projection c a -> Pi a b -> Projection c b
- Database.Relational.Query.ProjectableExtended: (!??) :: (PersistableWidth a, ProjectableMaybe (Projection cont), ProjectableFlattenMaybe (Maybe b) c) => Projection cont (Maybe a) -> Pi a b -> Projection cont c
- Database.Relational.Query.ProjectableExtended: (?!) :: PersistableWidth a => Projection c (Maybe a) -> Pi a b -> Projection c (Maybe b)
- Database.Relational.Query.ProjectableExtended: (?!?) :: PersistableWidth a => Projection c (Maybe a) -> Pi a (Maybe b) -> Projection c (Maybe b)
- Database.Relational.Query.ProjectableExtended: any' :: (AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)
- Database.Relational.Query.ProjectableExtended: avg :: (Num a, Fractional b, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat a -> p ac (Maybe b)
- Database.Relational.Query.ProjectableExtended: avgMaybe :: (Num a, Fractional b, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe a) -> p ac (Maybe b)
- Database.Relational.Query.ProjectableExtended: class ProjectableFlattenMaybe a b
- Database.Relational.Query.ProjectableExtended: class ProjectableApplicative p => ProjectableIdZip p
- Database.Relational.Query.ProjectableExtended: class ProjectableRunIdsZip a b
- Database.Relational.Query.ProjectableExtended: count :: (Integral b, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat a -> p ac b
- Database.Relational.Query.ProjectableExtended: every :: (AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)
- Database.Relational.Query.ProjectableExtended: flatten :: (ProjectableFlattenMaybe a b, ProjectableMaybe p) => p a -> p b
- Database.Relational.Query.ProjectableExtended: flattenPh :: ProjectableRunIdsZip a b => PlaceHolders a -> PlaceHolders b
- Database.Relational.Query.ProjectableExtended: flattenPiMaybe :: (PersistableWidth a, ProjectableMaybe (Projection cont), ProjectableFlattenMaybe (Maybe b) c) => Projection cont (Maybe a) -> Pi a b -> Projection cont c
- Database.Relational.Query.ProjectableExtended: infixl 8 !??
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.AggregatedContext Database.Relational.Query.Internal.ContextType.Aggregated
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.AggregatedContext Database.Relational.Query.Internal.ContextType.OverWindow
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe a) (GHC.Base.Maybe a)
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe a) b => Database.Relational.Query.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe (GHC.Base.Maybe a)) b
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.ProjectableRunIdsZip a a
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.ProjectableRunIdsZip a b => Database.Relational.Query.ProjectableExtended.ProjectableRunIdsZip ((), a) b
- Database.Relational.Query.ProjectableExtended: instance Database.Relational.Query.ProjectableExtended.ProjectableRunIdsZip a b => Database.Relational.Query.ProjectableExtended.ProjectableRunIdsZip (a, ()) b
- Database.Relational.Query.ProjectableExtended: leftId :: ProjectableIdZip p => p ((), a) -> p a
- Database.Relational.Query.ProjectableExtended: max' :: (Ord a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat a -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: maxMaybe :: (Ord a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe a) -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: min' :: (Ord a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat a -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: minMaybe :: (Ord a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe a) -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: rightId :: ProjectableIdZip p => p (a, ()) -> p a
- Database.Relational.Query.ProjectableExtended: runIds :: (ProjectableRunIdsZip a b, ProjectableIdZip p) => p a -> p b
- Database.Relational.Query.ProjectableExtended: some' :: (AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)
- Database.Relational.Query.ProjectableExtended: sum' :: (Num a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat a -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: sumMaybe :: (Num a, AggregatedContext ac, SqlProjectable (p ac)) => Projection Flat (Maybe a) -> p ac (Maybe a)
- Database.Relational.Query.ProjectableExtended: unsafeAggregateOp :: (AggregatedContext ac, SqlProjectable (p ac)) => Keyword -> Projection Flat a -> p ac b
- Database.Relational.Query.Projection: columns :: Projection c r -> [StringSQL]
- Database.Relational.Query.Projection: data ListProjection p t
- Database.Relational.Query.Projection: data Projection c t
- Database.Relational.Query.Projection: flattenMaybe :: Projection c (Maybe (Maybe a)) -> Projection c (Maybe a)
- Database.Relational.Query.Projection: instance Database.Relational.Query.ProjectableClass.ProjectableApplicative (Database.Relational.Query.Internal.Sub.Projection c)
- Database.Relational.Query.Projection: instance Database.Relational.Query.ProjectableClass.ProjectableFunctor (Database.Relational.Query.Internal.Sub.Projection c)
- Database.Relational.Query.Projection: just :: Projection c r -> Projection c (Maybe r)
- Database.Relational.Query.Projection: list :: [p t] -> ListProjection p t
- Database.Relational.Query.Projection: pap :: Projection c (a -> b) -> Projection c a -> Projection c b
- Database.Relational.Query.Projection: pfmap :: ProductConstructor (a -> b) => (a -> b) -> Projection c a -> Projection c b
- Database.Relational.Query.Projection: pi :: PersistableWidth a => Projection c a -> Pi a b -> Projection c b
- Database.Relational.Query.Projection: piMaybe :: PersistableWidth a => Projection c (Maybe a) -> Pi a b -> Projection c (Maybe b)
- Database.Relational.Query.Projection: piMaybe' :: PersistableWidth a => Projection c (Maybe a) -> Pi a (Maybe b) -> Projection c (Maybe b)
- Database.Relational.Query.Projection: unsafeChangeContext :: Projection c r -> Projection c' r
- Database.Relational.Query.Projection: unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Projection c t
- Database.Relational.Query.Projection: unsafeFromScalarSubQuery :: SubQuery -> Projection c t
- Database.Relational.Query.Projection: unsafeFromSqlTerms :: [StringSQL] -> Projection c t
- Database.Relational.Query.Projection: unsafeFromTable :: Table r -> Projection c r
- Database.Relational.Query.Projection: unsafeListFromSubQuery :: SubQuery -> ListProjection p t
- Database.Relational.Query.Projection: unsafeStringSql :: Projection c r -> StringSQL
- Database.Relational.Query.Projection: unsafeStringSqlList :: (p t -> StringSQL) -> ListProjection p t -> StringSQL
- Database.Relational.Query.Projection: unsafeStringSqlNotNullMaybe :: HasColumnConstraint NotNull r => Projection c (Maybe r) -> StringSQL
- Database.Relational.Query.Projection: unsafeToAggregated :: Projection Flat r -> Projection Aggregated r
- Database.Relational.Query.Projection: unsafeToFlat :: Projection Aggregated r -> Projection Flat r
- Database.Relational.Query.Projection: untype :: Projection c r -> UntypedProjection
- Database.Relational.Query.Projection: width :: Projection c r -> Int
- Database.Relational.Query.Projection: wpi :: PersistableRecordWidth a -> Projection c a -> Pi a b -> Projection c b
- Database.Relational.Query.Pure: instance (Database.Record.Persistable.PersistableWidth a, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (GHC.Base.Maybe a)
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL ()
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.ByteString.Internal.ByteString
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.ByteString.Lazy.Internal.ByteString
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Text.Internal.Lazy.Text
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Text.Internal.Text
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Time.Calendar.Days.Day
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Time.Clock.UTC.UTCTime
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.LocalTime.LocalTime
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.LocalTime.ZonedTime
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.TimeOfDay.TimeOfDay
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Base.String
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int16
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int32
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int64
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int8
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Types.Bool
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Types.Char
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Types.Double
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Types.Float
- Database.Relational.Query.Pure: instance Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL GHC.Types.Int
- Database.Relational.Query.Relation: aggregateRelation :: QueryAggregate (Projection Aggregated r) -> Relation () r
- Database.Relational.Query.Relation: aggregateRelation' :: AggregatedQuery p r -> Relation p r
- Database.Relational.Query.Relation: aggregatedUnique :: Relation ph r -> Pi r a -> (Projection Flat a -> Projection Aggregated b) -> UniqueRelation ph Flat b
- Database.Relational.Query.Relation: data UniqueRelation p c r
- Database.Relational.Query.Relation: derivedRelation :: TableDerivable r => Relation () r
- Database.Relational.Query.Relation: except :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: except' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: exceptAll :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: exceptAll' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: full :: Relation () a -> Relation () b -> [JoinRestriction (Maybe a) (Maybe b)] -> Relation () (Maybe a, Maybe b)
- Database.Relational.Query.Relation: full' :: Relation pa a -> Relation pb b -> [JoinRestriction (Maybe a) (Maybe b)] -> Relation (pa, pb) (Maybe a, Maybe b)
- Database.Relational.Query.Relation: infixl 7 `exceptAll'`
- Database.Relational.Query.Relation: infixl 8 `intersectAll'`
- Database.Relational.Query.Relation: inner :: Relation () a -> Relation () b -> [JoinRestriction a b] -> Relation () (a, b)
- Database.Relational.Query.Relation: inner' :: Relation pa a -> Relation pb b -> [JoinRestriction a b] -> Relation (pa, pb) (a, b)
- Database.Relational.Query.Relation: intersect :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: intersect' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: intersectAll :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: intersectAll' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: left :: Relation () a -> Relation () b -> [JoinRestriction a (Maybe b)] -> Relation () (a, Maybe b)
- Database.Relational.Query.Relation: left' :: Relation pa a -> Relation pb b -> [JoinRestriction a (Maybe b)] -> Relation (pa, pb) (a, Maybe b)
- Database.Relational.Query.Relation: on' :: ([JoinRestriction a b] -> Relation pc (a, b)) -> [JoinRestriction a b] -> Relation pc (a, b)
- Database.Relational.Query.Relation: query :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> m (Projection Flat r)
- Database.Relational.Query.Relation: queryList :: MonadQualify ConfigureQuery m => Relation () r -> m (ListProjection (Projection c) r)
- Database.Relational.Query.Relation: queryList' :: MonadQualify ConfigureQuery m => Relation p r -> m (PlaceHolders p, ListProjection (Projection c) r)
- Database.Relational.Query.Relation: queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> m (Projection Flat (Maybe r))
- Database.Relational.Query.Relation: queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation () c r -> m (Projection c (Maybe r))
- Database.Relational.Query.Relation: queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation p c r -> m (PlaceHolders p, Projection c (Maybe r))
- Database.Relational.Query.Relation: relation :: QuerySimple (Projection Flat r) -> Relation () r
- Database.Relational.Query.Relation: relation' :: SimpleQuery p r -> Relation p r
- Database.Relational.Query.Relation: right :: Relation () a -> Relation () b -> [JoinRestriction (Maybe a) b] -> Relation () (Maybe a, b)
- Database.Relational.Query.Relation: right' :: Relation pa a -> Relation pb b -> [JoinRestriction (Maybe a) b] -> Relation (pa, pb) (Maybe a, b)
- Database.Relational.Query.Relation: table :: Table r -> Relation () r
- Database.Relational.Query.Relation: tableOf :: TableDerivable r => Relation () r -> Table r
- Database.Relational.Query.Relation: type JoinRestriction a b = Projection Flat a -> Projection Flat b -> Projection Flat (Maybe Bool)
- Database.Relational.Query.Relation: unUnique :: UniqueRelation p c r -> Relation p r
- Database.Relational.Query.Relation: union :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: union' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: unionAll :: Relation () a -> Relation () a -> Relation () a
- Database.Relational.Query.Relation: unionAll' :: Relation p a -> Relation q a -> Relation (p, q) a
- Database.Relational.Query.Relation: uniqueQuery' :: UniqueRelation p c r -> QueryUnique (PlaceHolders p, Projection c r)
- Database.Relational.Query.Relation: uniqueQueryMaybe' :: UniqueRelation p c r -> QueryUnique (PlaceHolders p, Projection c (Maybe r))
- Database.Relational.Query.Relation: uniqueRelation' :: QueryUnique (PlaceHolders p, Projection c r) -> UniqueRelation p c r
- Database.Relational.Query.Relation: unsafeUnique :: Relation p r -> UniqueRelation p c r
- Database.Relational.Query.SQL: deletePrefixSQL :: Table r -> StringSQL
- Database.Relational.Query.SQL: deletePrefixSQL' :: String -> StringSQL
- Database.Relational.Query.SQL: insertPrefixSQL :: Pi r r' -> Table r -> StringSQL
- Database.Relational.Query.SQL: insertSQL :: PersistableWidth r => Pi r r' -> Table r -> String
- Database.Relational.Query.SQL: showsQuerySuffix :: QuerySuffix -> StringSQL
- Database.Relational.Query.SQL: type QuerySuffix = [Keyword]
- Database.Relational.Query.SQL: updateOtherThanKeySQL :: Table r -> Pi r p -> String
- Database.Relational.Query.SQL: updateOtherThanKeySQL' :: String -> [StringSQL] -> [Int] -> String
- Database.Relational.Query.SQL: updatePrefixSQL :: Table r -> StringSQL
- Database.Relational.Query.SQL: updateSQL' :: String -> [StringSQL] -> [StringSQL] -> String
- Database.Relational.Query.Scalar: class PersistableWidth ct => ScalarDegree ct
- Database.Relational.Query.Scalar: defineScalarDegree :: TypeQ -> Q [Dec]
- Database.Relational.Query.Scalar: instance Database.Relational.Query.Scalar.ScalarDegree ct => Database.Relational.Query.Scalar.ScalarDegree (GHC.Base.Maybe ct)
- Database.Relational.Query.Sub: Just' :: NodeAttr
- Database.Relational.Query.Sub: Maybe :: NodeAttr
- Database.Relational.Query.Sub: Qualifier :: Int -> Qualifier
- Database.Relational.Query.Sub: aggregatedSubQuery :: Config -> UntypedProjection -> Duplication -> JoinProduct -> QueryRestriction Flat -> [AggregateElem] -> QueryRestriction Aggregated -> [OrderingTerm] -> SubQuery
- Database.Relational.Query.Sub: column :: Qualified SubQuery -> Int -> StringSQL
- Database.Relational.Query.Sub: composeHaving :: QueryRestriction Aggregated -> StringSQL
- Database.Relational.Query.Sub: composeWhere :: QueryRestriction Flat -> StringSQL
- Database.Relational.Query.Sub: data NodeAttr
- Database.Relational.Query.Sub: data Projection c t
- Database.Relational.Query.Sub: data ProjectionUnit
- Database.Relational.Query.Sub: data Qualified a
- Database.Relational.Query.Sub: data SubQuery
- Database.Relational.Query.Sub: except :: Duplication -> SubQuery -> SubQuery -> SubQuery
- Database.Relational.Query.Sub: flatSubQuery :: Config -> UntypedProjection -> Duplication -> JoinProduct -> QueryRestriction Flat -> [OrderingTerm] -> SubQuery
- Database.Relational.Query.Sub: fromTable :: Table r -> SubQuery
- Database.Relational.Query.Sub: intersect :: Duplication -> SubQuery -> SubQuery -> SubQuery
- Database.Relational.Query.Sub: newtype Qualifier
- Database.Relational.Query.Sub: projectionColumns :: Projection c r -> [StringSQL]
- Database.Relational.Query.Sub: queryWidth :: Qualified SubQuery -> Int
- Database.Relational.Query.Sub: showSQL :: SubQuery -> StringSQL
- Database.Relational.Query.Sub: toSQL :: SubQuery -> String
- Database.Relational.Query.Sub: type JoinProduct = Maybe QueryProductTree
- Database.Relational.Query.Sub: type ProductBuilder = Node QueryRestrictionBuilder
- Database.Relational.Query.Sub: type QueryRestriction c = [Projection c (Maybe Bool)]
- Database.Relational.Query.Sub: type UntypedProjection = [ProjectionUnit]
- Database.Relational.Query.Sub: union :: Duplication -> SubQuery -> SubQuery -> SubQuery
- Database.Relational.Query.Sub: unitSQL :: SubQuery -> String
- Database.Relational.Query.Sub: unsafeProjectionStringSql :: Projection c r -> StringSQL
- Database.Relational.Query.Sub: untypedProjectionFromJoinedSubQuery :: Qualified SubQuery -> UntypedProjection
- Database.Relational.Query.Sub: width :: SubQuery -> Int
- Database.Relational.Query.TH: defineColumns :: ConName -> [((VarName, TypeQ), Maybe (TypeQ, VarName))] -> Q [Dec]
- Database.Relational.Query.TH: defineColumnsDefault :: ConName -> [((String, TypeQ), Maybe TypeQ)] -> Q [Dec]
- Database.Relational.Query.TH: defineHasNotNullKeyInstance :: TypeQ -> Int -> Q [Dec]
- Database.Relational.Query.TH: defineHasNotNullKeyInstanceWithConfig :: Config -> String -> String -> Int -> Q [Dec]
- Database.Relational.Query.TH: defineHasPrimaryKeyInstance :: TypeQ -> TypeQ -> [Int] -> Q [Dec]
- Database.Relational.Query.TH: defineHasPrimaryKeyInstanceWithConfig :: Config -> String -> String -> TypeQ -> [Int] -> Q [Dec]
- Database.Relational.Query.TH: definePrimaryQuery :: VarName -> TypeQ -> TypeQ -> ExpQ -> Q [Dec]
- Database.Relational.Query.TH: definePrimaryUpdate :: VarName -> TypeQ -> TypeQ -> ExpQ -> Q [Dec]
- Database.Relational.Query.TH: defineProductConstructorInstance :: TypeQ -> ExpQ -> [TypeQ] -> Q [Dec]
- Database.Relational.Query.TH: defineScalarDegree :: TypeQ -> Q [Dec]
- Database.Relational.Query.TH: defineSqlsWithPrimaryKey :: VarName -> VarName -> TypeQ -> TypeQ -> ExpQ -> ExpQ -> Q [Dec]
- Database.Relational.Query.TH: defineSqlsWithPrimaryKeyDefault :: String -> TypeQ -> TypeQ -> ExpQ -> ExpQ -> Q [Dec]
- Database.Relational.Query.TH: defineTable :: Config -> String -> String -> [(String, TypeQ)] -> [Name] -> [Int] -> Maybe Int -> Q [Dec]
- Database.Relational.Query.TH: defineTableTypes :: VarName -> VarName -> VarName -> VarName -> TypeQ -> String -> [String] -> Q [Dec]
- Database.Relational.Query.TH: defineTableTypesAndRecord :: Config -> String -> String -> [(String, TypeQ)] -> [Name] -> Q [Dec]
- Database.Relational.Query.TH: defineTableTypesWithConfig :: Config -> String -> String -> [((String, TypeQ), Maybe TypeQ)] -> Q [Dec]
- Database.Relational.Query.TH: defineTuplePi :: Int -> Q [Dec]
- Database.Relational.Query.TH: derivationExpDefault :: String -> ExpQ
- Database.Relational.Query.TH: inlineQuery :: Name -> Relation p r -> Config -> QuerySuffix -> String -> Q [Dec]
- Database.Relational.Query.TH: makeRelationalRecordDefault :: Name -> Q [Dec]
- Database.Relational.Query.TH: reifyRelation :: Name -> Q (Type, Type)
- Database.Relational.Query.TH: relationVarExp :: Config -> String -> String -> ExpQ
- Database.Relational.Query.TH: tableVarExpDefault :: String -> ExpQ
- Database.Relational.Query.TH: unsafeInlineQuery :: TypeQ -> TypeQ -> String -> VarName -> Q [Dec]
- Database.Relational.Query.Table: class PersistableWidth r => TableDerivable r
- Database.Relational.Query.Table: columns :: Table r -> [StringSQL]
- Database.Relational.Query.Table: data Table r
- Database.Relational.Query.Table: derivedTable :: TableDerivable r => Table r
- Database.Relational.Query.Table: index :: Table r -> Int -> StringSQL
- Database.Relational.Query.Table: name :: Table r -> String
- Database.Relational.Query.Table: recordWidth :: Table r -> PersistableRecordWidth r
- Database.Relational.Query.Table: shortName :: Table r -> String
- Database.Relational.Query.Table: table :: String -> [String] -> Table r
- Database.Relational.Query.Table: toMaybe :: Table r -> Table (Maybe r)
- Database.Relational.Query.Table: unType :: Table t -> Untyped
- Database.Relational.Query.Table: width :: Table r -> Int
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2)
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a3) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3)
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a4) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4)
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a5) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5)
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a5, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a6) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5, a6)
- Database.Relational.Query.TupleInstances: instance (Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a5, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a6, Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL a7) => Database.Relational.Query.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5, a6, a7)
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> (a1, a2))
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> a3 -> (a1, a2, a3))
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> a3 -> a4 -> (a1, a2, a3, a4))
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> a3 -> a4 -> a5 -> (a1, a2, a3, a4, a5))
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> (a1, a2, a3, a4, a5, a6))
- Database.Relational.Query.TupleInstances: instance Database.Relational.Query.ProjectableClass.ProductConstructor (a1 -> a2 -> a3 -> a4 -> a5 -> a6 -> a7 -> (a1, a2, a3, a4, a5, a6, a7))
- Database.Relational.Query.TupleInstances: tuplePi2_0' :: forall a1 a2. (PersistableWidth a1, PersistableWidth a2) => Pi (a1, a2) a1
- Database.Relational.Query.TupleInstances: tuplePi2_1' :: forall a1 a2. (PersistableWidth a1, PersistableWidth a2) => Pi (a1, a2) a2
- Database.Relational.Query.TupleInstances: tuplePi3_0' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a1
- Database.Relational.Query.TupleInstances: tuplePi3_1' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a2
- Database.Relational.Query.TupleInstances: tuplePi3_2' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a3
- Database.Relational.Query.TupleInstances: tuplePi4_0' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a1
- Database.Relational.Query.TupleInstances: tuplePi4_1' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a2
- Database.Relational.Query.TupleInstances: tuplePi4_2' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a3
- Database.Relational.Query.TupleInstances: tuplePi4_3' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a4
- Database.Relational.Query.TupleInstances: tuplePi5_0' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a1
- Database.Relational.Query.TupleInstances: tuplePi5_1' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a2
- Database.Relational.Query.TupleInstances: tuplePi5_2' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a3
- Database.Relational.Query.TupleInstances: tuplePi5_3' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a4
- Database.Relational.Query.TupleInstances: tuplePi5_4' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a5
- Database.Relational.Query.TupleInstances: tuplePi6_0' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a1
- Database.Relational.Query.TupleInstances: tuplePi6_1' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a2
- Database.Relational.Query.TupleInstances: tuplePi6_2' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a3
- Database.Relational.Query.TupleInstances: tuplePi6_3' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a4
- Database.Relational.Query.TupleInstances: tuplePi6_4' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a5
- Database.Relational.Query.TupleInstances: tuplePi6_5' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a6
- Database.Relational.Query.TupleInstances: tuplePi7_0' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a1
- Database.Relational.Query.TupleInstances: tuplePi7_1' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a2
- Database.Relational.Query.TupleInstances: tuplePi7_2' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a3
- Database.Relational.Query.TupleInstances: tuplePi7_3' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a4
- Database.Relational.Query.TupleInstances: tuplePi7_4' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a5
- Database.Relational.Query.TupleInstances: tuplePi7_5' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a6
- Database.Relational.Query.TupleInstances: tuplePi7_6' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a7
- Database.Relational.Query.Type: Delete :: String -> Delete p
- Database.Relational.Query.Type: Insert :: String -> Maybe (String, Int) -> Insert a
- Database.Relational.Query.Type: InsertQuery :: String -> InsertQuery p
- Database.Relational.Query.Type: KeyUpdate :: Pi a p -> String -> KeyUpdate p a
- Database.Relational.Query.Type: Query :: String -> Query p a
- Database.Relational.Query.Type: Update :: String -> Update p
- Database.Relational.Query.Type: [chunkedInsert] :: Insert a -> Maybe (String, Int)
- Database.Relational.Query.Type: [untypeDelete] :: Delete p -> String
- Database.Relational.Query.Type: [untypeInsertQuery] :: InsertQuery p -> String
- Database.Relational.Query.Type: [untypeInsert] :: Insert a -> String
- Database.Relational.Query.Type: [untypeKeyUpdate] :: KeyUpdate p a -> String
- Database.Relational.Query.Type: [untypeQuery] :: Query p a -> String
- Database.Relational.Query.Type: [untypeUpdate] :: Update p -> String
- Database.Relational.Query.Type: [updateKey] :: KeyUpdate p a -> Pi a p
- Database.Relational.Query.Type: chunkSizeOfInsert :: Insert a -> Int
- Database.Relational.Query.Type: class UntypeableNoFetch s
- Database.Relational.Query.Type: data Insert a
- Database.Relational.Query.Type: data KeyUpdate p a
- Database.Relational.Query.Type: deleteSQL :: Config -> Table r -> Restriction p r -> String
- Database.Relational.Query.Type: derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p
- Database.Relational.Query.Type: derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p
- Database.Relational.Query.Type: derivedInsert :: (PersistableWidth r, TableDerivable r) => Pi r r' -> Insert r'
- Database.Relational.Query.Type: derivedInsertQuery :: TableDerivable r => Pi r r' -> Relation p r' -> InsertQuery p
- Database.Relational.Query.Type: derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p
- Database.Relational.Query.Type: derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p
- Database.Relational.Query.Type: derivedKeyUpdate :: TableDerivable r => Pi r p -> KeyUpdate p r
- Database.Relational.Query.Type: derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p
- Database.Relational.Query.Type: derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p
- Database.Relational.Query.Type: derivedUpdateAllColumn :: (PersistableWidth r, TableDerivable r) => RestrictedStatement r (PlaceHolders p) -> Update (r, p)
- Database.Relational.Query.Type: derivedUpdateAllColumn' :: (PersistableWidth r, TableDerivable r) => Config -> RestrictedStatement r (PlaceHolders p) -> Update (r, p)
- Database.Relational.Query.Type: insertQuerySQL :: Config -> Table r -> Pi r r' -> Relation p r' -> String
- Database.Relational.Query.Type: instance Database.Relational.Query.Type.UntypeableNoFetch Database.Relational.Query.Type.Delete
- Database.Relational.Query.Type: instance Database.Relational.Query.Type.UntypeableNoFetch Database.Relational.Query.Type.Insert
- Database.Relational.Query.Type: instance Database.Relational.Query.Type.UntypeableNoFetch Database.Relational.Query.Type.InsertQuery
- Database.Relational.Query.Type: instance Database.Relational.Query.Type.UntypeableNoFetch Database.Relational.Query.Type.Update
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.Delete p)
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.Insert a)
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.InsertQuery p)
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.KeyUpdate p a)
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.Query p a)
- Database.Relational.Query.Type: instance GHC.Show.Show (Database.Relational.Query.Type.Update p)
- Database.Relational.Query.Type: newtype Delete p
- Database.Relational.Query.Type: newtype InsertQuery p
- Database.Relational.Query.Type: newtype Query p a
- Database.Relational.Query.Type: newtype Update p
- Database.Relational.Query.Type: relationalQuery :: Relation p r -> Query p r
- Database.Relational.Query.Type: relationalQuery' :: Relation p r -> QuerySuffix -> Query p r
- Database.Relational.Query.Type: relationalQuerySQL :: Config -> Relation p r -> QuerySuffix -> String
- Database.Relational.Query.Type: restrictedUpdateAllColumn :: PersistableWidth r => Table r -> RestrictedStatement r (PlaceHolders p) -> Update (r, p)
- Database.Relational.Query.Type: restrictedUpdateTableAllColumn :: (PersistableWidth r, TableDerivable r) => Relation () r -> RestrictedStatement r (PlaceHolders p) -> Update (r, p)
- Database.Relational.Query.Type: typedDelete :: Table r -> Restriction p r -> Delete p
- Database.Relational.Query.Type: typedDelete' :: Config -> Table r -> Restriction p r -> Delete p
- Database.Relational.Query.Type: typedInsert :: PersistableWidth r => Table r -> Pi r r' -> Insert r'
- Database.Relational.Query.Type: typedInsert' :: PersistableWidth r => Config -> Table r -> Pi r r' -> Insert r'
- Database.Relational.Query.Type: typedInsertQuery :: Table r -> Pi r r' -> Relation p r' -> InsertQuery p
- Database.Relational.Query.Type: typedInsertQuery' :: Config -> Table r -> Pi r r' -> Relation p r' -> InsertQuery p
- Database.Relational.Query.Type: typedInsertValue :: Table r -> InsertTarget p r -> Insert p
- Database.Relational.Query.Type: typedInsertValue' :: Config -> Table r -> InsertTarget p r -> Insert p
- Database.Relational.Query.Type: typedKeyUpdate :: Table a -> Pi a p -> KeyUpdate p a
- Database.Relational.Query.Type: typedKeyUpdateTable :: TableDerivable r => Relation () r -> Pi r p -> KeyUpdate p r
- Database.Relational.Query.Type: typedUpdate :: Table r -> UpdateTarget p r -> Update p
- Database.Relational.Query.Type: typedUpdate' :: Config -> Table r -> UpdateTarget p r -> Update p
- Database.Relational.Query.Type: typedUpdateAllColumn :: PersistableWidth r => Table r -> Restriction p r -> Update (r, p)
- Database.Relational.Query.Type: unsafeTypedDelete :: String -> Delete p
- Database.Relational.Query.Type: unsafeTypedInsert :: String -> Insert a
- Database.Relational.Query.Type: unsafeTypedInsert' :: String -> String -> Int -> Insert a
- Database.Relational.Query.Type: unsafeTypedInsertQuery :: String -> InsertQuery p
- Database.Relational.Query.Type: unsafeTypedKeyUpdate :: Pi a p -> String -> KeyUpdate p a
- Database.Relational.Query.Type: unsafeTypedQuery :: String -> Query p a
- Database.Relational.Query.Type: unsafeTypedUpdate :: String -> Update p
- Database.Relational.Query.Type: untypeChunkInsert :: Insert a -> String
- Database.Relational.Query.Type: untypeNoFetch :: UntypeableNoFetch s => s p -> String
- Database.Relational.Query.Type: updateSQL :: Config -> Table r -> UpdateTarget p r -> String
+ Database.Relational.Arrow: aggregateRelation :: QueryAggregate () (Record Aggregated r) -> Relation () r
+ Database.Relational.Arrow: aggregateRelation' :: QueryAggregate () (PlaceHolders p, Record Aggregated r) -> Relation p r
+ Database.Relational.Arrow: all' :: MonadQuery m => QueryA m () ()
+ Database.Relational.Arrow: asc :: Monad m => Orderings c m (Record c t) ()
+ Database.Relational.Arrow: assign :: Monad m => AssignTarget r v -> Assignings r m (Record Flat v) ()
+ Database.Relational.Arrow: bkey :: AggregatingPowerSet (Record Flat r) (Record Aggregated (Maybe r))
+ Database.Relational.Arrow: cube :: AggregatingPowerSet () a -> AggregateKey a
+ Database.Relational.Arrow: data QueryA m a b
+ Database.Relational.Arrow: derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p
+ Database.Relational.Arrow: derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p
+ Database.Relational.Arrow: derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p
+ Database.Relational.Arrow: derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p
+ Database.Relational.Arrow: derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p
+ Database.Relational.Arrow: derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p
+ Database.Relational.Arrow: desc :: Monad m => Orderings c m (Record c t) ()
+ Database.Relational.Arrow: distinct :: MonadQuery m => QueryA m () ()
+ Database.Relational.Arrow: groupBy :: MonadAggregate m => QueryA m (Record Flat r) (Record Aggregated r)
+ Database.Relational.Arrow: groupBy' :: MonadAggregate m => QueryA m (AggregateKey (Record Aggregated r)) (Record Aggregated r)
+ Database.Relational.Arrow: groupingSets :: AggregatingSetList () a -> AggregateKey a
+ Database.Relational.Arrow: having :: MonadRestrict Aggregated m => QueryA m (Predicate Aggregated) ()
+ Database.Relational.Arrow: infix 8 `over`
+ Database.Relational.Arrow: instance GHC.Base.Monad m => Control.Arrow.Arrow (Database.Relational.Arrow.QueryA m)
+ Database.Relational.Arrow: instance GHC.Base.Monad m => Control.Category.Category (Database.Relational.Arrow.QueryA m)
+ Database.Relational.Arrow: key :: AggregatingSet (Record Flat r) (Record Aggregated (Maybe r))
+ Database.Relational.Arrow: key' :: AggregatingSet (AggregateKey a) a
+ Database.Relational.Arrow: on :: MonadQuery m => QueryA m (Predicate Flat) ()
+ Database.Relational.Arrow: orderBy :: Monad m => Order -> Orderings c m (Record c t) ()
+ Database.Relational.Arrow: orderBy' :: Monad m => Order -> Nulls -> Orderings c m (Record c t) ()
+ Database.Relational.Arrow: over :: SqlContext c => Record OverWindow a -> Window c () () -> Record c a
+ Database.Relational.Arrow: partitionBy :: Window c (Record c r) ()
+ Database.Relational.Arrow: placeholder :: (PersistableWidth t, SqlContext c, Monad m) => QueryA m (QueryA m (Record c t) a) (PlaceHolders t, a)
+ Database.Relational.Arrow: query :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> QueryA m () (Record Flat r)
+ Database.Relational.Arrow: query' :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation p r -> QueryA m () (PlaceHolders p, Record Flat r)
+ Database.Relational.Arrow: queryExists :: MonadQualify ConfigureQuery m => (Record c a -> Relation () r) -> QueryA m (Record c a) (RecordList (Record Exists) r)
+ Database.Relational.Arrow: queryExists' :: MonadQualify ConfigureQuery m => (Record c a -> Relation p r) -> QueryA m (Record c a) (PlaceHolders p, RecordList (Record Exists) r)
+ Database.Relational.Arrow: queryList :: MonadQualify ConfigureQuery m => (Record c a -> Relation () r) -> QueryA m (Record c a) (RecordList (Record c) r)
+ Database.Relational.Arrow: queryList' :: MonadQualify ConfigureQuery m => (Record c a -> Relation p r) -> QueryA m (Record c a) (PlaceHolders p, RecordList (Record c) r)
+ Database.Relational.Arrow: queryListU :: MonadQualify ConfigureQuery m => Relation () r -> QueryA m () (RecordList (Record c) r)
+ Database.Relational.Arrow: queryListU' :: MonadQualify ConfigureQuery m => Relation p r -> QueryA m () (PlaceHolders p, RecordList (Record c) r)
+ Database.Relational.Arrow: queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> QueryA m () (Record Flat (Maybe r))
+ Database.Relational.Arrow: queryMaybe' :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation p r -> QueryA m () (PlaceHolders p, Record Flat (Maybe r))
+ Database.Relational.Arrow: queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r) => (Record c a -> UniqueRelation () c r) -> QueryA m (Record c a) (Record c (Maybe r))
+ Database.Relational.Arrow: queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => (Record c a -> UniqueRelation p c r) -> QueryA m (Record c a) (PlaceHolders p, Record c (Maybe r))
+ Database.Relational.Arrow: queryScalarU :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation () c r -> QueryA m () (Record c (Maybe r))
+ Database.Relational.Arrow: queryScalarU' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation p c r -> QueryA m () (PlaceHolders p, Record c (Maybe r))
+ Database.Relational.Arrow: relation :: QuerySimple () (Record Flat r) -> Relation () r
+ Database.Relational.Arrow: relation' :: QuerySimple () (PlaceHolders p, Record Flat r) -> Relation p r
+ Database.Relational.Arrow: rollup :: AggregatingPowerSet () a -> AggregateKey a
+ Database.Relational.Arrow: set :: AggregatingSetList (AggregatingSet () a) a
+ Database.Relational.Arrow: type AggregatingPowerSet = QueryA AggregatingPowerSet
+ Database.Relational.Arrow: type AggregatingSet = QueryA AggregatingSet
+ Database.Relational.Arrow: type AggregatingSetList = QueryA AggregatingSetList
+ Database.Relational.Arrow: type AssignStatement r a = Assignings r Restrict (Record Flat r) a
+ Database.Relational.Arrow: type Assignings r m = QueryA (Assignings r m)
+ Database.Relational.Arrow: type Orderings c m = QueryA (Orderings c m)
+ Database.Relational.Arrow: type QueryAggregate = QueryA QueryAggregate
+ Database.Relational.Arrow: type QuerySimple = QueryA QuerySimple
+ Database.Relational.Arrow: type QueryUnique = QueryA QueryUnique
+ Database.Relational.Arrow: type Register r a = QueryA (Register r) () a
+ Database.Relational.Arrow: type RestrictedStatement r a = QueryA Restrict (Record Flat r) a
+ Database.Relational.Arrow: type Window c = QueryA (Window c)
+ Database.Relational.Arrow: uniqueQuery' :: UniqueRelation p c r -> QueryA QueryUnique () (PlaceHolders p, Record c r)
+ Database.Relational.Arrow: uniqueQueryMaybe' :: UniqueRelation p c r -> QueryA QueryUnique () (PlaceHolders p, Record c (Maybe r))
+ Database.Relational.Arrow: uniqueRelation' :: QueryUnique () (PlaceHolders p, Record c r) -> UniqueRelation p c r
+ Database.Relational.Arrow: wheres :: MonadRestrict Flat m => QueryA m (Predicate Flat) ()
+ Database.Relational.BaseTH: defineRecordProjections :: TypeQ -> [Name] -> [Name] -> [TypeQ] -> Q [Dec]
+ Database.Relational.BaseTH: defineTuplePi :: Int -> Q [Dec]
+ Database.Relational.BaseTH: defineTupleShowConstantInstance :: Int -> Q [Dec]
+ Database.Relational.Compat: (|$|) :: ProductIsoFunctor f => forall a b. ProductConstructor (a -> b) => (a -> b) -> f a -> f b
+ Database.Relational.Compat: (|*|) :: ProductIsoApplicative f => forall a b. f (a -> b) -> f a -> f b
+ Database.Relational.Compat: class ProductConstructor c
+ Database.Relational.Compat: class ProjectableShowSql p
+ Database.Relational.Compat: class SqlProjectable p
+ Database.Relational.Compat: instance Database.Relational.Compat.ProjectableShowSql (Database.Relational.SqlSyntax.Types.Record c)
+ Database.Relational.Compat: instance Database.Relational.Projectable.SqlContext c => Database.Relational.Compat.SqlProjectable (Database.Relational.SqlSyntax.Types.Record c)
+ Database.Relational.Compat: leftId :: ProjectableIdZip p => p ((), a) -> p a
+ Database.Relational.Compat: pap :: Pi r (a -> b) -> Pi r a -> Pi r b
+ Database.Relational.Compat: pfmap :: ProductConstructor (a -> b) => (a -> b) -> Pi r a -> Pi r b
+ Database.Relational.Compat: productConstructor :: ProductConstructor c => c
+ Database.Relational.Compat: pzero :: Pi a ()
+ Database.Relational.Compat: rightId :: ProjectableIdZip p => p (a, ()) -> p a
+ Database.Relational.Compat: type ListProjection = RecordList
+ Database.Relational.Compat: type ProjectableApplicative = ProductIsoApplicative
+ Database.Relational.Compat: type ProjectableFunctor = ProductIsoFunctor
+ Database.Relational.Compat: type ProjectableIdZip p = ProductIsoEmpty p ()
+ Database.Relational.Compat: type Projection = Record
+ Database.Relational.Compat: unsafeProjectSql :: SqlProjectable p => String -> p a
+ Database.Relational.Compat: unsafeProjectSqlTerms :: SqlProjectable p => [StringSQL] -> p t
+ Database.Relational.Compat: unsafeShowSql :: ProjectableShowSql p => p a -> String
+ Database.Relational.Compat: unsafeShowSql' :: ProjectableShowSql p => p a -> StringSQL
+ Database.Relational.Config: NameConfig :: NameConfig -> (String -> String -> VarName) -> NameConfig
+ Database.Relational.Config: NoQuotation :: IdentifierQuotation
+ Database.Relational.Config: PUNotSupported :: ProductUnitSupport
+ Database.Relational.Config: PUSupported :: ProductUnitSupport
+ Database.Relational.Config: Quotation :: Char -> IdentifierQuotation
+ Database.Relational.Config: SchemaNotQualified :: SchemaNameMode
+ Database.Relational.Config: SchemaQualified :: SchemaNameMode
+ Database.Relational.Config: [recordConfig] :: NameConfig -> NameConfig
+ Database.Relational.Config: [relationVarName] :: NameConfig -> String -> String -> VarName
+ Database.Relational.Config: data Config
+ Database.Relational.Config: data IdentifierQuotation
+ Database.Relational.Config: data NameConfig
+ Database.Relational.Config: data ProductUnitSupport
+ Database.Relational.Config: data SchemaNameMode
+ Database.Relational.Config: defaultConfig :: Config
+ Database.Relational.Constraint: class PersistableWidth ct => HasConstraintKey c r ct
+ Database.Relational.Constraint: constraintKey :: HasConstraintKey c r ct => Key c r ct
+ Database.Relational.Constraint: data Key c r ct
+ Database.Relational.Constraint: data NotNull :: *
+ Database.Relational.Constraint: data Primary :: *
+ Database.Relational.Constraint: data Unique :: *
+ Database.Relational.Constraint: derivedUniqueKey :: HasConstraintKey Primary r ct => Key Unique r ct
+ Database.Relational.Constraint: indexes :: Key c r ct -> [Int]
+ Database.Relational.Constraint: projectionKey :: Key c r ct -> Pi r ct
+ Database.Relational.Constraint: tableConstraint :: Key c r ct -> KeyConstraint c r
+ Database.Relational.Constraint: uniqueKey :: PersistableWidth ct => Key Primary r ct -> Key Unique r ct
+ Database.Relational.Constraint: unsafeDefineConstraintKey :: PersistableWidth ct => [Int] -> Key c r ct
+ Database.Relational.Context: data Aggregated
+ Database.Relational.Context: data Exists
+ Database.Relational.Context: data Flat
+ Database.Relational.Context: data OverWindow
+ Database.Relational.Context: data Power
+ Database.Relational.Context: data Set
+ Database.Relational.Context: data SetList
+ Database.Relational.Derives: derivedUniqueRelation :: TableDerivable r => Key Unique r k -> Record c k -> UniqueRelation () c r
+ Database.Relational.Derives: primary :: HasConstraintKey Primary a p => Relation () a -> Relation p a
+ Database.Relational.Derives: primary' :: PersistableWidth p => Key Primary a p -> Relation () a -> Relation p a
+ Database.Relational.Derives: primaryUpdate :: (HasConstraintKey Primary r p) => Table r -> KeyUpdate p r
+ Database.Relational.Derives: specifiedKey :: PersistableWidth p => Pi a p -> Relation () a -> Relation p a
+ Database.Relational.Derives: unique :: PersistableWidth p => Key Unique a p -> Relation () a -> Relation p a
+ Database.Relational.Derives: updateByConstraintKey :: Table r -> Key c r p -> KeyUpdate p r
+ Database.Relational.Derives: updateValuesWithKey :: ToSql q r => Pi r p -> r -> [q]
+ Database.Relational.Effect: data InsertTarget p r
+ Database.Relational.Effect: data Restriction p r
+ Database.Relational.Effect: data UpdateTarget p r
+ Database.Relational.Effect: insertTarget :: Register r () -> InsertTarget () r
+ Database.Relational.Effect: insertTarget' :: Register r (PlaceHolders p) -> InsertTarget p r
+ Database.Relational.Effect: instance Database.Relational.Table.TableDerivable r => GHC.Show.Show (Database.Relational.Effect.Restriction p r)
+ Database.Relational.Effect: instance Database.Relational.Table.TableDerivable r => GHC.Show.Show (Database.Relational.Effect.UpdateTarget p r)
+ Database.Relational.Effect: liftTargetAllColumn :: PersistableWidth r => Restriction () r -> UpdateTarget r r
+ Database.Relational.Effect: liftTargetAllColumn' :: PersistableWidth r => Restriction p r -> UpdateTarget (r, p) r
+ Database.Relational.Effect: piRegister :: PersistableWidth r => Pi r r' -> Register r (PlaceHolders r')
+ Database.Relational.Effect: restriction :: RestrictedStatement r () -> Restriction () r
+ Database.Relational.Effect: restriction' :: RestrictedStatement r (PlaceHolders p) -> Restriction p r
+ Database.Relational.Effect: sqlChunkFromInsertTarget :: Config -> Table r -> InsertTarget p r -> (StringSQL, Int)
+ Database.Relational.Effect: sqlFromInsertTarget :: Config -> Table r -> InsertTarget p r -> StringSQL
+ Database.Relational.Effect: sqlFromUpdateTarget :: Config -> Table r -> UpdateTarget p r -> StringSQL
+ Database.Relational.Effect: sqlWhereFromRestriction :: Config -> Table r -> Restriction p r -> StringSQL
+ Database.Relational.Effect: updateTarget :: AssignStatement r () -> UpdateTarget () r
+ Database.Relational.Effect: updateTarget' :: AssignStatement r (PlaceHolders p) -> UpdateTarget p r
+ Database.Relational.Effect: updateTargetAllColumn :: PersistableWidth r => RestrictedStatement r () -> UpdateTarget r r
+ Database.Relational.Effect: updateTargetAllColumn' :: PersistableWidth r => RestrictedStatement r (PlaceHolders p) -> UpdateTarget (r, p) r
+ Database.Relational.Monad.Aggregate: infix 8 `over`
+ Database.Relational.Monad.Aggregate: instance Database.Relational.Monad.Class.MonadRestrict Database.Relational.Internal.ContextType.Flat q => Database.Relational.Monad.Class.MonadRestrict Database.Relational.Internal.ContextType.Flat (Database.Relational.Monad.Trans.Restricting.Restrictings Database.Relational.Internal.ContextType.Aggregated q)
+ Database.Relational.Monad.Aggregate: over :: SqlContext c => Record OverWindow a -> Window c () -> Record c a
+ Database.Relational.Monad.Aggregate: toSQL :: AggregatedQuery p r -> ConfigureQuery String
+ Database.Relational.Monad.Aggregate: toSubQuery :: AggregatedQuery p r -> ConfigureQuery SubQuery
+ Database.Relational.Monad.Aggregate: type AggregatedQuery p r = OrderedQuery Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore)) p r
+ Database.Relational.Monad.Aggregate: type QueryAggregate = Orderings Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore))
+ Database.Relational.Monad.Aggregate: type Window c = Orderings c (PartitioningSet c)
+ Database.Relational.Monad.Assign: extract :: Assign r a -> Config -> ((a, Table r -> [Assignment]), [Predicate Flat])
+ Database.Relational.Monad.Assign: type Assign r = Assignings r Restrict
+ Database.Relational.Monad.Assign: type AssignStatement r a = Record Flat r -> Assign r a
+ Database.Relational.Monad.BaseType: askConfig :: ConfigureQuery Config
+ Database.Relational.Monad.BaseType: configureQuery :: ConfigureQuery q -> Config -> q
+ Database.Relational.Monad.BaseType: data Relation p r
+ Database.Relational.Monad.BaseType: dump :: Relation p r -> String
+ Database.Relational.Monad.BaseType: instance GHC.Show.Show (Database.Relational.Monad.BaseType.Relation p r)
+ Database.Relational.Monad.BaseType: leftPh :: Relation (p, ()) r -> Relation p r
+ Database.Relational.Monad.BaseType: qualifyQuery :: a -> ConfigureQuery (Qualified a)
+ Database.Relational.Monad.BaseType: relationWidth :: Relation p r -> PersistableRecordWidth r
+ Database.Relational.Monad.BaseType: rightPh :: Relation ((), p) r -> Relation p r
+ Database.Relational.Monad.BaseType: sqlFromRelation :: Relation p r -> StringSQL
+ Database.Relational.Monad.BaseType: sqlFromRelationWith :: Relation p r -> Config -> StringSQL
+ Database.Relational.Monad.BaseType: type ConfigureQuery = Qualify (QueryConfig Identity)
+ Database.Relational.Monad.BaseType: unsafeTypeRelation :: ConfigureQuery SubQuery -> Relation p r
+ Database.Relational.Monad.BaseType: untypeRelation :: Relation p r -> ConfigureQuery SubQuery
+ Database.Relational.Monad.Class: all' :: MonadQuery m => m ()
+ Database.Relational.Monad.Class: class MonadQuery m => MonadAggregate m
+ Database.Relational.Monad.Class: class Monad m => MonadPartition c m
+ Database.Relational.Monad.Class: class (Functor q, Monad q, Functor m, Monad m) => MonadQualify q m
+ Database.Relational.Monad.Class: class (Functor m, Monad m, MonadQualify ConfigureQuery m) => MonadQuery m
+ Database.Relational.Monad.Class: class (Functor m, Monad m) => MonadRestrict c m
+ Database.Relational.Monad.Class: distinct :: MonadQuery m => m ()
+ Database.Relational.Monad.Class: groupBy :: MonadAggregate m => Record Flat r -> m (Record Aggregated r)
+ Database.Relational.Monad.Class: groupBy' :: MonadAggregate m => AggregateKey (Record Aggregated r) -> m (Record Aggregated r)
+ Database.Relational.Monad.Class: having :: MonadRestrict Aggregated m => Predicate Aggregated -> m ()
+ Database.Relational.Monad.Class: instance (GHC.Base.Functor q, GHC.Base.Monad q) => Database.Relational.Monad.Class.MonadQualify q q
+ Database.Relational.Monad.Class: liftQualify :: MonadQualify q m => q a -> m a
+ Database.Relational.Monad.Class: on :: MonadQuery m => Predicate Flat -> m ()
+ Database.Relational.Monad.Class: partitionBy :: MonadPartition c m => Record c r -> m ()
+ Database.Relational.Monad.Class: query' :: MonadQuery m => Relation p r -> m (PlaceHolders p, Record Flat r)
+ Database.Relational.Monad.Class: queryMaybe' :: MonadQuery m => Relation p r -> m (PlaceHolders p, Record Flat (Maybe r))
+ Database.Relational.Monad.Class: restrict :: MonadRestrict c m => Predicate c -> m ()
+ Database.Relational.Monad.Class: restrictJoin :: MonadQuery m => Predicate Flat -> m ()
+ Database.Relational.Monad.Class: setDuplication :: MonadQuery m => Duplication -> m ()
+ Database.Relational.Monad.Class: wheres :: MonadRestrict Flat m => Predicate Flat -> m ()
+ Database.Relational.Monad.Register: extract :: Assignings r ConfigureQuery a -> Config -> (a, Table r -> [Assignment])
+ Database.Relational.Monad.Register: type Register r = Assignings r ConfigureQuery
+ Database.Relational.Monad.Restrict: extract :: Restrict a -> Config -> (a, [Predicate Flat])
+ Database.Relational.Monad.Restrict: type Restrict = Restrictings Flat ConfigureQuery
+ Database.Relational.Monad.Restrict: type RestrictedStatement r a = Record Flat r -> Restrict a
+ Database.Relational.Monad.Simple: simple :: ConfigureQuery a -> QuerySimple a
+ Database.Relational.Monad.Simple: toSQL :: SimpleQuery p r -> ConfigureQuery String
+ Database.Relational.Monad.Simple: toSubQuery :: SimpleQuery p r -> ConfigureQuery SubQuery
+ Database.Relational.Monad.Simple: type QuerySimple = Orderings Flat QueryCore
+ Database.Relational.Monad.Simple: type SimpleQuery p r = OrderedQuery Flat QueryCore p r
+ Database.Relational.Monad.Trans.Aggregating: aggregatings :: Monad m => m a -> Aggregatings ac at m a
+ Database.Relational.Monad.Trans.Aggregating: bkey :: Record Flat r -> AggregatingPowerSet (Record Aggregated (Maybe r))
+ Database.Relational.Monad.Trans.Aggregating: cube :: AggregatingPowerSet a -> AggregateKey a
+ Database.Relational.Monad.Trans.Aggregating: data Aggregatings ac at m a
+ Database.Relational.Monad.Trans.Aggregating: extractAggregateTerms :: (Monad m, Functor m) => Aggregatings ac at m a -> m (a, [at])
+ Database.Relational.Monad.Trans.Aggregating: groupingSets :: AggregatingSetList a -> AggregateKey a
+ Database.Relational.Monad.Trans.Aggregating: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Monad.Trans.Aggregating.Aggregatings ac at)
+ Database.Relational.Monad.Trans.Aggregating: instance Database.Relational.Monad.Class.MonadQualify q m => Database.Relational.Monad.Class.MonadQualify q (Database.Relational.Monad.Trans.Aggregating.AggregatingSetT m)
+ Database.Relational.Monad.Trans.Aggregating: instance Database.Relational.Monad.Class.MonadQuery m => Database.Relational.Monad.Class.MonadAggregate (Database.Relational.Monad.Trans.Aggregating.AggregatingSetT m)
+ Database.Relational.Monad.Trans.Aggregating: instance Database.Relational.Monad.Class.MonadQuery m => Database.Relational.Monad.Class.MonadQuery (Database.Relational.Monad.Trans.Aggregating.AggregatingSetT m)
+ Database.Relational.Monad.Trans.Aggregating: instance Database.Relational.Monad.Class.MonadRestrict c m => Database.Relational.Monad.Class.MonadRestrict c (Database.Relational.Monad.Trans.Aggregating.AggregatingSetT m)
+ Database.Relational.Monad.Trans.Aggregating: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Aggregating.Aggregatings ac at m)
+ Database.Relational.Monad.Trans.Aggregating: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Aggregating.Aggregatings ac at m)
+ Database.Relational.Monad.Trans.Aggregating: instance GHC.Base.Monad m => Database.Relational.Monad.Class.MonadPartition c (Database.Relational.Monad.Trans.Aggregating.PartitioningSetT c m)
+ Database.Relational.Monad.Trans.Aggregating: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Aggregating.Aggregatings ac at m)
+ Database.Relational.Monad.Trans.Aggregating: key :: Record Flat r -> AggregatingSet (Record Aggregated (Maybe r))
+ Database.Relational.Monad.Trans.Aggregating: key' :: AggregateKey a -> AggregatingSet a
+ Database.Relational.Monad.Trans.Aggregating: rollup :: AggregatingPowerSet a -> AggregateKey a
+ Database.Relational.Monad.Trans.Aggregating: set :: AggregatingSet a -> AggregatingSetList a
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingPowerSet = AggregatingPowerSetT Identity
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingPowerSetT = Aggregatings Power AggregateBitKey
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingSet = AggregatingSetT Identity
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingSetList = AggregatingSetListT Identity
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingSetListT = Aggregatings SetList AggregateSet
+ Database.Relational.Monad.Trans.Aggregating: type AggregatingSetT = Aggregatings Set AggregateElem
+ Database.Relational.Monad.Trans.Aggregating: type PartitioningSet c = PartitioningSetT c Identity
+ Database.Relational.Monad.Trans.Aggregating: type PartitioningSetT c = Aggregatings c AggregateColumnRef
+ Database.Relational.Monad.Trans.Assigning: (<-#) :: Monad m => AssignTarget r v -> Record Flat v -> Assignings r m ()
+ Database.Relational.Monad.Trans.Assigning: assignTo :: Monad m => Record Flat v -> AssignTarget r v -> Assignings r m ()
+ Database.Relational.Monad.Trans.Assigning: assignings :: Monad m => m a -> Assignings r m a
+ Database.Relational.Monad.Trans.Assigning: data Assignings r m a
+ Database.Relational.Monad.Trans.Assigning: extractAssignments :: (Monad m, Functor m) => Assignings r m a -> m (a, Table r -> [Assignment])
+ Database.Relational.Monad.Trans.Assigning: infix 4 <-#
+ Database.Relational.Monad.Trans.Assigning: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Monad.Trans.Assigning.Assignings r)
+ Database.Relational.Monad.Trans.Assigning: instance Database.Relational.Monad.Class.MonadQualify q m => Database.Relational.Monad.Class.MonadQualify q (Database.Relational.Monad.Trans.Assigning.Assignings r m)
+ Database.Relational.Monad.Trans.Assigning: instance Database.Relational.Monad.Class.MonadRestrict c m => Database.Relational.Monad.Class.MonadRestrict c (Database.Relational.Monad.Trans.Assigning.Assignings r m)
+ Database.Relational.Monad.Trans.Assigning: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Assigning.Assignings r m)
+ Database.Relational.Monad.Trans.Assigning: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Assigning.Assignings r m)
+ Database.Relational.Monad.Trans.Assigning: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Assigning.Assignings r m)
+ Database.Relational.Monad.Trans.Assigning: type AssignTarget r v = Pi r v
+ Database.Relational.Monad.Trans.Config: askQueryConfig :: Monad m => QueryConfig m Config
+ Database.Relational.Monad.Trans.Config: data QueryConfig m a
+ Database.Relational.Monad.Trans.Config: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Config.QueryConfig m)
+ Database.Relational.Monad.Trans.Config: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Config.QueryConfig m)
+ Database.Relational.Monad.Trans.Config: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Config.QueryConfig m)
+ Database.Relational.Monad.Trans.Config: queryConfig :: Monad m => m a -> QueryConfig m a
+ Database.Relational.Monad.Trans.Config: runQueryConfig :: QueryConfig m a -> Config -> m a
+ Database.Relational.Monad.Trans.Join: data QueryJoin m a
+ Database.Relational.Monad.Trans.Join: extractProduct :: Functor m => QueryJoin m a -> m ((a, JoinProduct), Duplication)
+ Database.Relational.Monad.Trans.Join: instance Control.Monad.Trans.Class.MonadTrans Database.Relational.Monad.Trans.Join.QueryJoin
+ Database.Relational.Monad.Trans.Join: instance Database.Relational.Monad.Class.MonadQualify q m => Database.Relational.Monad.Class.MonadQualify q (Database.Relational.Monad.Trans.Join.QueryJoin m)
+ Database.Relational.Monad.Trans.Join: instance Database.Relational.Monad.Class.MonadQuery (Database.Relational.Monad.Trans.Join.QueryJoin Database.Relational.Monad.BaseType.ConfigureQuery)
+ Database.Relational.Monad.Trans.Join: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Join.QueryJoin m)
+ Database.Relational.Monad.Trans.Join: instance GHC.Base.Monad m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Join.QueryJoin m)
+ Database.Relational.Monad.Trans.Join: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Join.QueryJoin m)
+ Database.Relational.Monad.Trans.Join: join' :: Monad m => m a -> QueryJoin m a
+ Database.Relational.Monad.Trans.Join: unsafeSubQueryWithAttr :: Monad q => NodeAttr -> Qualified SubQuery -> QueryJoin q (Record c r)
+ Database.Relational.Monad.Trans.Ordering: asc :: Monad m => Record c t -> Orderings c m ()
+ Database.Relational.Monad.Trans.Ordering: data Orderings c m a
+ Database.Relational.Monad.Trans.Ordering: desc :: Monad m => Record c t -> Orderings c m ()
+ Database.Relational.Monad.Trans.Ordering: extractOrderingTerms :: (Monad m, Functor m) => Orderings c m a -> m (a, [OrderingTerm])
+ Database.Relational.Monad.Trans.Ordering: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Monad.Trans.Ordering.Orderings c)
+ Database.Relational.Monad.Trans.Ordering: instance Database.Relational.Monad.Class.MonadAggregate m => Database.Relational.Monad.Class.MonadAggregate (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance Database.Relational.Monad.Class.MonadPartition c m => Database.Relational.Monad.Class.MonadPartition c (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance Database.Relational.Monad.Class.MonadQualify q m => Database.Relational.Monad.Class.MonadQualify q (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance Database.Relational.Monad.Class.MonadQuery m => Database.Relational.Monad.Class.MonadQuery (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance Database.Relational.Monad.Class.MonadRestrict rc m => Database.Relational.Monad.Class.MonadRestrict rc (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Ordering.Orderings c m)
+ Database.Relational.Monad.Trans.Ordering: orderBy :: Monad m => Record c t -> Order -> Orderings c m ()
+ Database.Relational.Monad.Trans.Ordering: orderBy' :: Monad m => Record c t -> Order -> Nulls -> Orderings c m ()
+ Database.Relational.Monad.Trans.Ordering: orderings :: Monad m => m a -> Orderings c m a
+ Database.Relational.Monad.Trans.Restricting: data Restrictings c m a
+ Database.Relational.Monad.Trans.Restricting: extractRestrict :: (Monad m, Functor m) => Restrictings c m a -> m (a, [Predicate c])
+ Database.Relational.Monad.Trans.Restricting: instance (GHC.Base.Monad q, GHC.Base.Functor q) => Database.Relational.Monad.Class.MonadRestrict c (Database.Relational.Monad.Trans.Restricting.Restrictings c q)
+ Database.Relational.Monad.Trans.Restricting: instance Control.Monad.Trans.Class.MonadTrans (Database.Relational.Monad.Trans.Restricting.Restrictings c)
+ Database.Relational.Monad.Trans.Restricting: instance Database.Relational.Monad.Class.MonadAggregate m => Database.Relational.Monad.Class.MonadAggregate (Database.Relational.Monad.Trans.Restricting.Restrictings c m)
+ Database.Relational.Monad.Trans.Restricting: instance Database.Relational.Monad.Class.MonadQualify q m => Database.Relational.Monad.Class.MonadQualify q (Database.Relational.Monad.Trans.Restricting.Restrictings c m)
+ Database.Relational.Monad.Trans.Restricting: instance Database.Relational.Monad.Class.MonadQuery q => Database.Relational.Monad.Class.MonadQuery (Database.Relational.Monad.Trans.Restricting.Restrictings c q)
+ Database.Relational.Monad.Trans.Restricting: instance GHC.Base.Applicative m => GHC.Base.Applicative (Database.Relational.Monad.Trans.Restricting.Restrictings c m)
+ Database.Relational.Monad.Trans.Restricting: instance GHC.Base.Functor m => GHC.Base.Functor (Database.Relational.Monad.Trans.Restricting.Restrictings c m)
+ Database.Relational.Monad.Trans.Restricting: instance GHC.Base.Monad m => GHC.Base.Monad (Database.Relational.Monad.Trans.Restricting.Restrictings c m)
+ Database.Relational.Monad.Trans.Restricting: restrictings :: Monad m => m a -> Restrictings c m a
+ Database.Relational.Monad.Type: extractCore :: QueryCore a -> ConfigureQuery (((a, [Predicate Flat]), JoinProduct), Duplication)
+ Database.Relational.Monad.Type: type OrderedQuery c m p r = Orderings c m (PlaceHolders p, Record c r)
+ Database.Relational.Monad.Type: type QueryCore = Restrictings Flat (QueryJoin ConfigureQuery)
+ Database.Relational.Monad.Unique: data QueryUnique a
+ Database.Relational.Monad.Unique: instance Database.Relational.Monad.Class.MonadQualify Database.Relational.Monad.BaseType.ConfigureQuery Database.Relational.Monad.Unique.QueryUnique
+ Database.Relational.Monad.Unique: instance Database.Relational.Monad.Class.MonadQuery Database.Relational.Monad.Unique.QueryUnique
+ Database.Relational.Monad.Unique: instance GHC.Base.Applicative Database.Relational.Monad.Unique.QueryUnique
+ Database.Relational.Monad.Unique: instance GHC.Base.Functor Database.Relational.Monad.Unique.QueryUnique
+ Database.Relational.Monad.Unique: instance GHC.Base.Monad Database.Relational.Monad.Unique.QueryUnique
+ Database.Relational.Monad.Unique: toSubQuery :: QueryUnique (PlaceHolders p, Record c r) -> ConfigureQuery SubQuery
+ Database.Relational.Monad.Unique: unsafeUniqueSubQuery :: NodeAttr -> Qualified SubQuery -> QueryUnique (Record c r)
+ Database.Relational.Pi: (<.>) :: Pi a b -> Pi b c -> Pi a c
+ Database.Relational.Pi: (<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)
+ Database.Relational.Pi: (<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)
+ Database.Relational.Pi: data Pi r0 r1
+ Database.Relational.Pi: fst' :: PersistableWidth a => Pi (a, b) a
+ Database.Relational.Pi: id' :: Pi a a
+ Database.Relational.Pi: infixl 8 <?.?>
+ Database.Relational.Pi: snd' :: (PersistableWidth a, PersistableWidth b) => Pi (a, b) b
+ Database.Relational.Pi.Unsafe: (<.>) :: Pi a b -> Pi b c -> Pi a c
+ Database.Relational.Pi.Unsafe: (<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)
+ Database.Relational.Pi.Unsafe: (<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)
+ Database.Relational.Pi.Unsafe: data Pi r0 r1
+ Database.Relational.Pi.Unsafe: defineDirectPi :: PersistableWidth r1 => [Int] -> Pi r0 r1
+ Database.Relational.Pi.Unsafe: defineDirectPi' :: PersistableRecordWidth r1 -> [Int] -> Pi r0 r1
+ Database.Relational.Pi.Unsafe: definePi :: PersistableWidth r1 => Int -> Pi r0 r1
+ Database.Relational.Pi.Unsafe: infixl 8 <?.?>
+ Database.Relational.Pi.Unsafe: instance Control.Category.Category Database.Relational.Pi.Unsafe.Pi
+ Database.Relational.Pi.Unsafe: instance Data.Functor.ProductIsomorphic.Class.ProductIsoApplicative (Database.Relational.Pi.Unsafe.Pi a)
+ Database.Relational.Pi.Unsafe: instance Data.Functor.ProductIsomorphic.Class.ProductIsoEmpty (Database.Relational.Pi.Unsafe.Pi a) ()
+ Database.Relational.Pi.Unsafe: instance Data.Functor.ProductIsomorphic.Class.ProductIsoFunctor (Database.Relational.Pi.Unsafe.Pi a)
+ Database.Relational.Pi.Unsafe: instance Database.Record.Persistable.PersistableWidth r0 => GHC.Show.Show (Database.Relational.Pi.Unsafe.Pi r0 r1)
+ Database.Relational.Pi.Unsafe: pi :: PersistableRecordWidth r0 -> Pi r0 r1 -> [a] -> [a]
+ Database.Relational.Pi.Unsafe: unsafeExpandIndexes :: PersistableWidth a => Pi a b -> [Int]
+ Database.Relational.Pi.Unsafe: unsafeExpandIndexes' :: PersistableRecordWidth a -> Pi a b -> [Int]
+ Database.Relational.Pi.Unsafe: width :: PersistableWidth r => Pi r a -> Int
+ Database.Relational.Pi.Unsafe: width' :: PersistableWidth r => Pi r ct -> PersistableRecordWidth ct
+ Database.Relational.Projectable: (.*.) :: (OperatorContext c, Num a) => Record c a -> Record c a -> Record c a
+ Database.Relational.Projectable: (.+.) :: (OperatorContext c, Num a) => Record c a -> Record c a -> Record c a
+ Database.Relational.Projectable: (.-.) :: (OperatorContext c, Num a) => Record c a -> Record c a -> Record c a
+ Database.Relational.Projectable: (./.) :: (OperatorContext c, Num a) => Record c a -> Record c a -> Record c a
+ Database.Relational.Projectable: (.<.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.<=.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.<>.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.=.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.>.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.>=.) :: OperatorContext c => Record c ft -> Record c ft -> Record c (Maybe Bool)
+ Database.Relational.Projectable: (.||.) :: OperatorContext c => Record c a -> Record c a -> Record c a
+ Database.Relational.Projectable: (><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)
+ Database.Relational.Projectable: (?*?) :: (OperatorContext c, Num a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: (?+?) :: (OperatorContext c, Num a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: (?-?) :: (OperatorContext c, Num a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: (?/?) :: (OperatorContext c, Num a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: (?||?) :: (OperatorContext c, IsString a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: and' :: OperatorContext c => Record c (Maybe Bool) -> Record c (Maybe Bool) -> Record c (Maybe Bool)
+ Database.Relational.Projectable: case' :: OperatorContext c => Record c a -> [(Record c a, Record c b)] -> Record c b -> Record c b
+ Database.Relational.Projectable: caseMaybe :: (OperatorContext c, PersistableWidth b) => Record c a -> [(Record c a, Record c (Maybe b))] -> Record c (Maybe b)
+ Database.Relational.Projectable: caseSearch :: OperatorContext c => [(Predicate c, Record c a)] -> Record c a -> Record c a
+ Database.Relational.Projectable: caseSearchMaybe :: (OperatorContext c, PersistableWidth a) => [(Predicate c, Record c (Maybe a))] -> Record c (Maybe a)
+ Database.Relational.Projectable: casesOrElse :: OperatorContext c => [(Predicate c, Record c a)] -> Record c a -> Record c a
+ Database.Relational.Projectable: casesOrElse' :: OperatorContext c => (Record c a, [(Record c a, Record c b)]) -> Record c b -> Record c b
+ Database.Relational.Projectable: class ProjectableMaybe p
+ Database.Relational.Projectable: class SqlContext c
+ Database.Relational.Projectable: cumeDist :: Record OverWindow Double
+ Database.Relational.Projectable: data PlaceHolders p
+ Database.Relational.Projectable: denseRank :: Integral a => Record OverWindow a
+ Database.Relational.Projectable: exists :: OperatorContext c => RecordList (Record Exists) r -> Record c (Maybe Bool)
+ Database.Relational.Projectable: flattenMaybe :: ProjectableMaybe p => p (Maybe (Maybe a)) -> p (Maybe a)
+ Database.Relational.Projectable: fromIntegral' :: (SqlContext c, Integral a, Num b) => Record c a -> Record c b
+ Database.Relational.Projectable: fromIntegralMaybe :: (SqlContext c, Integral a, Num b) => Record c (Maybe a) -> Record c (Maybe b)
+ Database.Relational.Projectable: fromMaybe :: (OperatorContext c, HasColumnConstraint NotNull r) => Record c r -> Record c (Maybe r) -> Record c r
+ Database.Relational.Projectable: in' :: OperatorContext c => Record c t -> RecordList (Record c) t -> Record c (Maybe Bool)
+ Database.Relational.Projectable: infix 4 `likeMaybe'`
+ Database.Relational.Projectable: infixl 1 ><
+ Database.Relational.Projectable: infixl 5 ?||?
+ Database.Relational.Projectable: infixl 6 ?-?
+ Database.Relational.Projectable: infixl 7 ?/?
+ Database.Relational.Projectable: infixr 2 `or'`
+ Database.Relational.Projectable: infixr 3 `and'`
+ Database.Relational.Projectable: instance Data.Functor.ProductIsomorphic.Class.ProductIsoApplicative Database.Relational.Projectable.PlaceHolders
+ Database.Relational.Projectable: instance Data.Functor.ProductIsomorphic.Class.ProductIsoEmpty Database.Relational.Projectable.PlaceHolders ()
+ Database.Relational.Projectable: instance Data.Functor.ProductIsomorphic.Class.ProductIsoFunctor Database.Relational.Projectable.PlaceHolders
+ Database.Relational.Projectable: instance Database.Relational.Projectable.OperatorContext Database.Relational.Internal.ContextType.Aggregated
+ Database.Relational.Projectable: instance Database.Relational.Projectable.OperatorContext Database.Relational.Internal.ContextType.Flat
+ Database.Relational.Projectable: instance Database.Relational.Projectable.ProjectableMaybe (Database.Relational.SqlSyntax.Types.Record c)
+ Database.Relational.Projectable: instance Database.Relational.Projectable.ProjectableMaybe Database.Relational.Projectable.PlaceHolders
+ Database.Relational.Projectable: instance Database.Relational.Projectable.SqlContext Database.Relational.Internal.ContextType.Aggregated
+ Database.Relational.Projectable: instance Database.Relational.Projectable.SqlContext Database.Relational.Internal.ContextType.Flat
+ Database.Relational.Projectable: instance Database.Relational.Projectable.SqlContext Database.Relational.Internal.ContextType.OverWindow
+ Database.Relational.Projectable: isJust :: (OperatorContext c, HasColumnConstraint NotNull r) => Record c (Maybe r) -> Predicate c
+ Database.Relational.Projectable: isNothing :: (OperatorContext c, HasColumnConstraint NotNull r) => Record c (Maybe r) -> Predicate c
+ Database.Relational.Projectable: just :: ProjectableMaybe p => p a -> p (Maybe a)
+ Database.Relational.Projectable: like :: (OperatorContext c, IsString a, ShowConstantTermsSQL a) => Record c a -> a -> Record c (Maybe Bool)
+ Database.Relational.Projectable: like' :: (OperatorContext c, IsString a) => Record c a -> Record c a -> Record c (Maybe Bool)
+ Database.Relational.Projectable: likeMaybe :: (OperatorContext c, IsString a, ShowConstantTermsSQL a) => Record c (Maybe a) -> a -> Record c (Maybe Bool)
+ Database.Relational.Projectable: likeMaybe' :: (OperatorContext c, IsString a) => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe Bool)
+ Database.Relational.Projectable: negate' :: (OperatorContext c, Num a) => Record c a -> Record c a
+ Database.Relational.Projectable: negateMaybe :: (OperatorContext c, Num a) => Record c (Maybe a) -> Record c (Maybe a)
+ Database.Relational.Projectable: not' :: OperatorContext c => Record c (Maybe Bool) -> Record c (Maybe Bool)
+ Database.Relational.Projectable: nothing :: (OperatorContext c, SqlContext c, PersistableWidth a) => Record c (Maybe a)
+ Database.Relational.Projectable: or' :: OperatorContext c => Record c (Maybe Bool) -> Record c (Maybe Bool) -> Record c (Maybe Bool)
+ Database.Relational.Projectable: percentRank :: Record OverWindow Double
+ Database.Relational.Projectable: placeholder :: (PersistableWidth t, SqlContext c, Monad m) => (Record c t -> m a) -> m (PlaceHolders t, a)
+ Database.Relational.Projectable: placeholder' :: (PersistableWidth t, SqlContext c) => (Record c t -> a) -> (PlaceHolders t, a)
+ Database.Relational.Projectable: projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)
+ Database.Relational.Projectable: pwPlaceholder :: SqlContext c => PersistableRecordWidth a -> (Record c a -> b) -> (PlaceHolders a, b)
+ Database.Relational.Projectable: rank :: Integral a => Record OverWindow a
+ Database.Relational.Projectable: rowNumber :: Integral a => Record OverWindow a
+ Database.Relational.Projectable: showNum :: (SqlContext c, Num a, IsString b) => Record c a -> Record c b
+ Database.Relational.Projectable: showNumMaybe :: (SqlContext c, Num a, IsString b) => Record c (Maybe a) -> Record c (Maybe b)
+ Database.Relational.Projectable: type SqlBinOp = Keyword -> Keyword -> Keyword
+ Database.Relational.Projectable: unitPH :: PlaceHolders ()
+ Database.Relational.Projectable: unitPlaceHolder :: PlaceHolders ()
+ Database.Relational.Projectable: unsafeAddPlaceHolders :: Functor f => f a -> f (PlaceHolders p, a)
+ Database.Relational.Projectable: unsafeBinOp :: SqlContext k => SqlBinOp -> Record k a -> Record k b -> Record k c
+ Database.Relational.Projectable: unsafePlaceHolders :: PlaceHolders p
+ Database.Relational.Projectable: unsafeProjectSql :: SqlContext c => String -> Record c t
+ Database.Relational.Projectable: unsafeProjectSql' :: SqlContext c => StringSQL -> Record c t
+ Database.Relational.Projectable: unsafeProjectSqlTerms :: SqlContext c => [StringSQL] -> Record c t
+ Database.Relational.Projectable: unsafeShowSql :: Record c a -> String
+ Database.Relational.Projectable: unsafeShowSql' :: Record c a -> StringSQL
+ Database.Relational.Projectable: unsafeUniOp :: SqlContext c2 => (Keyword -> Keyword) -> Record c1 a -> Record c2 b
+ Database.Relational.Projectable: value :: (ShowConstantTermsSQL t, OperatorContext c) => t -> Record c t
+ Database.Relational.Projectable: valueFalse :: (OperatorContext c, ProjectableMaybe (Record c)) => Record c (Maybe Bool)
+ Database.Relational.Projectable: valueTrue :: (OperatorContext c, ProjectableMaybe (Record c)) => Record c (Maybe Bool)
+ Database.Relational.Projectable: values :: (ShowConstantTermsSQL t, OperatorContext c) => [t] -> RecordList (Record c) t
+ Database.Relational.ProjectableClass: class ShowConstantTermsSQL a where showConstantTermsSQL' = gShowConstantTermsSQL . from
+ Database.Relational.ProjectableClass: instance (Database.Relational.ProjectableClass.GShowConstantTermsSQL a, Database.Relational.ProjectableClass.GShowConstantTermsSQL b) => Database.Relational.ProjectableClass.GShowConstantTermsSQL (a GHC.Generics.:*: b)
+ Database.Relational.ProjectableClass: instance Database.Relational.ProjectableClass.GShowConstantTermsSQL GHC.Generics.U1
+ Database.Relational.ProjectableClass: instance Database.Relational.ProjectableClass.GShowConstantTermsSQL a => Database.Relational.ProjectableClass.GShowConstantTermsSQL (GHC.Generics.M1 i c a)
+ Database.Relational.ProjectableClass: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL a => Database.Relational.ProjectableClass.GShowConstantTermsSQL (GHC.Generics.K1 i a)
+ Database.Relational.ProjectableClass: showConstantTermsSQL :: ShowConstantTermsSQL a => a -> [StringSQL]
+ Database.Relational.ProjectableClass: showConstantTermsSQL' :: (ShowConstantTermsSQL a, Generic a, GShowConstantTermsSQL (Rep a)) => a -> DList StringSQL
+ Database.Relational.ProjectableClass: type StringSQL = Keyword
+ Database.Relational.ProjectableExtended: (!) :: PersistableWidth a => Record c a -> Pi a b -> Record c b
+ Database.Relational.ProjectableExtended: (!??) :: (PersistableWidth a, ProjectableMaybe (Record cont), ProjectableFlattenMaybe (Maybe b) c) => Record cont (Maybe a) -> Pi a b -> Record cont c
+ Database.Relational.ProjectableExtended: (?!) :: PersistableWidth a => Record c (Maybe a) -> Pi a b -> Record c (Maybe b)
+ Database.Relational.ProjectableExtended: (?!?) :: PersistableWidth a => Record c (Maybe a) -> Pi a (Maybe b) -> Record c (Maybe b)
+ Database.Relational.ProjectableExtended: any' :: (AggregatedContext ac, SqlContext ac) => Predicate Flat -> Record ac (Maybe Bool)
+ Database.Relational.ProjectableExtended: avg :: (Num a, Fractional b, AggregatedContext ac, SqlContext ac) => Record Flat a -> Record ac (Maybe b)
+ Database.Relational.ProjectableExtended: avgMaybe :: (Num a, Fractional b, AggregatedContext ac, SqlContext ac) => Record Flat (Maybe a) -> Record ac (Maybe b)
+ Database.Relational.ProjectableExtended: class ProjectableFlattenMaybe a b
+ Database.Relational.ProjectableExtended: count :: (Integral b, AggregatedContext ac, SqlContext ac) => Record Flat a -> Record ac b
+ Database.Relational.ProjectableExtended: every :: (AggregatedContext ac, SqlContext ac) => Predicate Flat -> Record ac (Maybe Bool)
+ Database.Relational.ProjectableExtended: flatten :: (ProjectableFlattenMaybe a b, ProjectableMaybe p) => p a -> p b
+ Database.Relational.ProjectableExtended: flattenPiMaybe :: (PersistableWidth a, ProjectableMaybe (Record cont), ProjectableFlattenMaybe (Maybe b) c) => Record cont (Maybe a) -> Pi a b -> Record cont c
+ Database.Relational.ProjectableExtended: infixl 8 !??
+ Database.Relational.ProjectableExtended: instance Database.Relational.ProjectableExtended.AggregatedContext Database.Relational.Internal.ContextType.Aggregated
+ Database.Relational.ProjectableExtended: instance Database.Relational.ProjectableExtended.AggregatedContext Database.Relational.Internal.ContextType.OverWindow
+ Database.Relational.ProjectableExtended: instance Database.Relational.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe a) (GHC.Base.Maybe a)
+ Database.Relational.ProjectableExtended: instance Database.Relational.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe a) b => Database.Relational.ProjectableExtended.ProjectableFlattenMaybe (GHC.Base.Maybe (GHC.Base.Maybe a)) b
+ Database.Relational.ProjectableExtended: max' :: (Ord a, AggregatedContext ac, SqlContext ac) => Record Flat a -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: maxMaybe :: (Ord a, AggregatedContext ac, SqlContext ac) => Record Flat (Maybe a) -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: min' :: (Ord a, AggregatedContext ac, SqlContext ac) => Record Flat a -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: minMaybe :: (Ord a, AggregatedContext ac, SqlContext ac) => Record Flat (Maybe a) -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: some' :: (AggregatedContext ac, SqlContext ac) => Predicate Flat -> Record ac (Maybe Bool)
+ Database.Relational.ProjectableExtended: sum' :: (Num a, AggregatedContext ac, SqlContext ac) => Record Flat a -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: sumMaybe :: (Num a, AggregatedContext ac, SqlContext ac) => Record Flat (Maybe a) -> Record ac (Maybe a)
+ Database.Relational.ProjectableExtended: unsafeAggregateOp :: (AggregatedContext ac, SqlContext ac) => Keyword -> Record Flat a -> Record ac b
+ Database.Relational.Pure: instance (Database.Record.Persistable.PersistableWidth a, Database.Relational.ProjectableClass.ShowConstantTermsSQL a) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (GHC.Base.Maybe a)
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL ()
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.ByteString.Internal.ByteString
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.ByteString.Lazy.Internal.ByteString
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Text.Internal.Lazy.Text
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Text.Internal.Text
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Time.Calendar.Days.Day
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Time.Clock.UTC.UTCTime
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.LocalTime.LocalTime
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.LocalTime.ZonedTime
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL Data.Time.LocalTime.TimeOfDay.TimeOfDay
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Base.String
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int16
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int32
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int64
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Int.Int8
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Types.Bool
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Types.Char
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Types.Double
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Types.Float
+ Database.Relational.Pure: instance Database.Relational.ProjectableClass.ShowConstantTermsSQL GHC.Types.Int
+ Database.Relational.Record: columns :: Record c r -> [StringSQL]
+ Database.Relational.Record: data Record c t
+ Database.Relational.Record: data RecordList p t
+ Database.Relational.Record: flattenMaybe :: Record c (Maybe (Maybe a)) -> Record c (Maybe a)
+ Database.Relational.Record: instance Data.Functor.ProductIsomorphic.Class.ProductIsoApplicative (Database.Relational.SqlSyntax.Types.Record c)
+ Database.Relational.Record: instance Data.Functor.ProductIsomorphic.Class.ProductIsoEmpty (Database.Relational.SqlSyntax.Types.Record c) ()
+ Database.Relational.Record: instance Data.Functor.ProductIsomorphic.Class.ProductIsoFunctor (Database.Relational.SqlSyntax.Types.Record c)
+ Database.Relational.Record: just :: Record c r -> Record c (Maybe r)
+ Database.Relational.Record: list :: [p t] -> RecordList p t
+ Database.Relational.Record: pi :: PersistableWidth a => Record c a -> Pi a b -> Record c b
+ Database.Relational.Record: piMaybe :: PersistableWidth a => Record c (Maybe a) -> Pi a b -> Record c (Maybe b)
+ Database.Relational.Record: piMaybe' :: PersistableWidth a => Record c (Maybe a) -> Pi a (Maybe b) -> Record c (Maybe b)
+ Database.Relational.Record: unsafeChangeContext :: Record c r -> Record c' r
+ Database.Relational.Record: unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Record c t
+ Database.Relational.Record: unsafeFromScalarSubQuery :: SubQuery -> Record c t
+ Database.Relational.Record: unsafeFromSqlTerms :: [StringSQL] -> Record c t
+ Database.Relational.Record: unsafeFromTable :: Table r -> Record c r
+ Database.Relational.Record: unsafeListFromSubQuery :: SubQuery -> RecordList p t
+ Database.Relational.Record: unsafeStringSql :: Record c r -> StringSQL
+ Database.Relational.Record: unsafeStringSqlList :: (p t -> StringSQL) -> RecordList p t -> StringSQL
+ Database.Relational.Record: unsafeStringSqlNotNullMaybe :: HasColumnConstraint NotNull r => Record c (Maybe r) -> StringSQL
+ Database.Relational.Record: unsafeToAggregated :: Record Flat r -> Record Aggregated r
+ Database.Relational.Record: unsafeToFlat :: Record Aggregated r -> Record Flat r
+ Database.Relational.Record: untype :: Record c r -> Tuple
+ Database.Relational.Record: width :: Record c r -> Int
+ Database.Relational.Record: wpi :: PersistableRecordWidth a -> Record c a -> Pi a b -> Record c b
+ Database.Relational.Relation: aggregateRelation :: QueryAggregate (Record Aggregated r) -> Relation () r
+ Database.Relational.Relation: aggregateRelation' :: AggregatedQuery p r -> Relation p r
+ Database.Relational.Relation: aggregatedUnique :: Relation ph r -> Pi r a -> (Record Flat a -> Record Aggregated b) -> UniqueRelation ph Flat b
+ Database.Relational.Relation: data UniqueRelation p c r
+ Database.Relational.Relation: derivedRelation :: TableDerivable r => Relation () r
+ Database.Relational.Relation: query :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> m (Record Flat r)
+ Database.Relational.Relation: queryList :: MonadQualify ConfigureQuery m => Relation () r -> m (RecordList (Record c) r)
+ Database.Relational.Relation: queryList' :: MonadQualify ConfigureQuery m => Relation p r -> m (PlaceHolders p, RecordList (Record c) r)
+ Database.Relational.Relation: queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m) => Relation () r -> m (Record Flat (Maybe r))
+ Database.Relational.Relation: queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation () c r -> m (Record c (Maybe r))
+ Database.Relational.Relation: queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r) => UniqueRelation p c r -> m (PlaceHolders p, Record c (Maybe r))
+ Database.Relational.Relation: relation :: QuerySimple (Record Flat r) -> Relation () r
+ Database.Relational.Relation: relation' :: SimpleQuery p r -> Relation p r
+ Database.Relational.Relation: table :: Table r -> Relation () r
+ Database.Relational.Relation: tableOf :: TableDerivable r => Relation () r -> Table r
+ Database.Relational.Relation: unUnique :: UniqueRelation p c r -> Relation p r
+ Database.Relational.Relation: uniqueQuery' :: UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c r)
+ Database.Relational.Relation: uniqueQueryMaybe' :: UniqueRelation p c r -> QueryUnique (PlaceHolders p, Record c (Maybe r))
+ Database.Relational.Relation: uniqueRelation' :: QueryUnique (PlaceHolders p, Record c r) -> UniqueRelation p c r
+ Database.Relational.Relation: unsafeUnique :: Relation p r -> UniqueRelation p c r
+ Database.Relational.Scalar: class PersistableWidth ct => ScalarDegree ct
+ Database.Relational.Scalar: defineScalarDegree :: TypeQ -> Q [Dec]
+ Database.Relational.Scalar: instance Database.Relational.Scalar.ScalarDegree ct => Database.Relational.Scalar.ScalarDegree (GHC.Base.Maybe ct)
+ Database.Relational.Set: except :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: except' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.Set: exceptAll :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: exceptAll' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.Set: full :: Relation () a -> Relation () b -> [JoinRestriction (Maybe a) (Maybe b)] -> Relation () (Maybe a, Maybe b)
+ Database.Relational.Set: full' :: Relation pa a -> Relation pb b -> [JoinRestriction (Maybe a) (Maybe b)] -> Relation (pa, pb) (Maybe a, Maybe b)
+ Database.Relational.Set: infixl 7 `exceptAll'`
+ Database.Relational.Set: infixl 8 `intersectAll'`
+ Database.Relational.Set: inner :: Relation () a -> Relation () b -> [JoinRestriction a b] -> Relation () (a, b)
+ Database.Relational.Set: inner' :: Relation pa a -> Relation pb b -> [JoinRestriction a b] -> Relation (pa, pb) (a, b)
+ Database.Relational.Set: intersect :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: intersect' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.Set: intersectAll :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: intersectAll' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.Set: left :: Relation () a -> Relation () b -> [JoinRestriction a (Maybe b)] -> Relation () (a, Maybe b)
+ Database.Relational.Set: left' :: Relation pa a -> Relation pb b -> [JoinRestriction a (Maybe b)] -> Relation (pa, pb) (a, Maybe b)
+ Database.Relational.Set: on' :: ([JoinRestriction a b] -> Relation pc (a, b)) -> [JoinRestriction a b] -> Relation pc (a, b)
+ Database.Relational.Set: right :: Relation () a -> Relation () b -> [JoinRestriction (Maybe a) b] -> Relation () (Maybe a, b)
+ Database.Relational.Set: right' :: Relation pa a -> Relation pb b -> [JoinRestriction (Maybe a) b] -> Relation (pa, pb) (Maybe a, b)
+ Database.Relational.Set: type JoinRestriction a b = Record Flat a -> Record Flat b -> Predicate Flat
+ Database.Relational.Set: union :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: union' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.Set: unionAll :: Relation () a -> Relation () a -> Relation () a
+ Database.Relational.Set: unionAll' :: Relation p a -> Relation q a -> Relation (p, q) a
+ Database.Relational.SimpleSql: deletePrefixSQL :: Table r -> StringSQL
+ Database.Relational.SimpleSql: insertPrefixSQL :: Pi r r' -> Table r -> StringSQL
+ Database.Relational.SimpleSql: showsQuerySuffix :: QuerySuffix -> StringSQL
+ Database.Relational.SimpleSql: type QuerySuffix = [Keyword]
+ Database.Relational.SimpleSql: updateOtherThanKeySQL :: Table r -> Pi r p -> String
+ Database.Relational.SimpleSql: updatePrefixSQL :: Table r -> StringSQL
+ Database.Relational.SqlSyntax: AggregateBitKey :: [AggregateColumnRef] -> AggregateBitKey
+ Database.Relational.SqlSyntax: AggregateKey :: (a, AggregateElem) -> AggregateKey a
+ Database.Relational.SqlSyntax: AggregateSet :: [AggregateElem] -> AggregateSet
+ Database.Relational.SqlSyntax: Aggregated :: Config -> Tuple -> Duplication -> JoinProduct -> [Predicate Flat] -> [AggregateElem] -> [Predicate Aggregated] -> [OrderingTerm] -> SubQuery
+ Database.Relational.SqlSyntax: All :: Duplication
+ Database.Relational.SqlSyntax: Asc :: Order
+ Database.Relational.SqlSyntax: Bin :: BinOp -> SubQuery -> SubQuery -> SubQuery
+ Database.Relational.SqlSyntax: BinOp :: (SetOp, Duplication) -> BinOp
+ Database.Relational.SqlSyntax: Case :: CaseClause -> Int -> Column
+ Database.Relational.SqlSyntax: CaseSearch :: WhenClauses -> CaseClause
+ Database.Relational.SqlSyntax: CaseSimple :: Tuple -> WhenClauses -> CaseClause
+ Database.Relational.SqlSyntax: ColumnRef :: AggregateColumnRef -> AggregateElem
+ Database.Relational.SqlSyntax: Cube :: [AggregateBitKey] -> AggregateElem
+ Database.Relational.SqlSyntax: Desc :: Order
+ Database.Relational.SqlSyntax: Distinct :: Duplication
+ Database.Relational.SqlSyntax: Except :: SetOp
+ Database.Relational.SqlSyntax: Flat :: Config -> Tuple -> Duplication -> JoinProduct -> [Predicate Flat] -> [OrderingTerm] -> SubQuery
+ Database.Relational.SqlSyntax: GroupingSets :: [AggregateSet] -> AggregateElem
+ Database.Relational.SqlSyntax: Intersect :: SetOp
+ Database.Relational.SqlSyntax: Join :: !(Node rs) -> !(Node rs) -> !rs -> ProductTree rs
+ Database.Relational.SqlSyntax: Just' :: NodeAttr
+ Database.Relational.SqlSyntax: Leaf :: QS -> ProductTree rs
+ Database.Relational.SqlSyntax: Maybe :: NodeAttr
+ Database.Relational.SqlSyntax: Node :: !NodeAttr -> !(ProductTree rs) -> Node rs
+ Database.Relational.SqlSyntax: NullsFirst :: Nulls
+ Database.Relational.SqlSyntax: NullsLast :: Nulls
+ Database.Relational.SqlSyntax: Qualified :: Qualifier -> a -> Qualified a
+ Database.Relational.SqlSyntax: Qualifier :: Int -> Qualifier
+ Database.Relational.SqlSyntax: RawColumn :: StringSQL -> Column
+ Database.Relational.SqlSyntax: Rollup :: [AggregateBitKey] -> AggregateElem
+ Database.Relational.SqlSyntax: Scalar :: SubQuery -> Column
+ Database.Relational.SqlSyntax: SubQueryRef :: (Qualified Int) -> Column
+ Database.Relational.SqlSyntax: Table :: Untyped -> SubQuery
+ Database.Relational.SqlSyntax: Union :: SetOp
+ Database.Relational.SqlSyntax: WhenClauses :: [(Tuple, Tuple)] -> Tuple -> WhenClauses
+ Database.Relational.SqlSyntax: aggregateColumnRef :: AggregateColumnRef -> AggregateElem
+ Database.Relational.SqlSyntax: aggregateCube :: [AggregateBitKey] -> AggregateElem
+ Database.Relational.SqlSyntax: aggregateGroupingSet :: [AggregateElem] -> AggregateSet
+ Database.Relational.SqlSyntax: aggregateKeyElement :: AggregateKey a -> AggregateElem
+ Database.Relational.SqlSyntax: aggregateKeyRecord :: AggregateKey a -> a
+ Database.Relational.SqlSyntax: aggregatePowerKey :: [AggregateColumnRef] -> AggregateBitKey
+ Database.Relational.SqlSyntax: aggregateRollup :: [AggregateBitKey] -> AggregateElem
+ Database.Relational.SqlSyntax: aggregateSets :: [AggregateSet] -> AggregateElem
+ Database.Relational.SqlSyntax: aggregatedSubQuery :: Config -> Tuple -> Duplication -> JoinProduct -> [Predicate Flat] -> [AggregateElem] -> [Predicate Aggregated] -> [OrderingTerm] -> SubQuery
+ Database.Relational.SqlSyntax: case' :: Record c a -> [(Record c a, Record c b)] -> Record c b -> Record c b
+ Database.Relational.SqlSyntax: caseSearch :: [(Predicate c, Record c a)] -> Record c a -> Record c a
+ Database.Relational.SqlSyntax: column :: Qualified SubQuery -> Int -> StringSQL
+ Database.Relational.SqlSyntax: composeChunkValues :: Int -> [AssignTerm] -> Keyword
+ Database.Relational.SqlSyntax: composeChunkValuesWithColumns :: Int -> [Assignment] -> StringSQL
+ Database.Relational.SqlSyntax: composeGroupBy :: [AggregateElem] -> StringSQL
+ Database.Relational.SqlSyntax: composeHaving :: [Predicate Aggregated] -> StringSQL
+ Database.Relational.SqlSyntax: composeOrderBy :: [OrderingTerm] -> StringSQL
+ Database.Relational.SqlSyntax: composePartitionBy :: [AggregateColumnRef] -> StringSQL
+ Database.Relational.SqlSyntax: composeSets :: [Assignment] -> StringSQL
+ Database.Relational.SqlSyntax: composeWhere :: [Predicate Flat] -> StringSQL
+ Database.Relational.SqlSyntax: data AggregateElem
+ Database.Relational.SqlSyntax: data CaseClause
+ Database.Relational.SqlSyntax: data Column
+ Database.Relational.SqlSyntax: data Duplication
+ Database.Relational.SqlSyntax: data Node rs
+ Database.Relational.SqlSyntax: data NodeAttr
+ Database.Relational.SqlSyntax: data Nulls
+ Database.Relational.SqlSyntax: data Order
+ Database.Relational.SqlSyntax: data ProductTree rs
+ Database.Relational.SqlSyntax: data Qualified a
+ Database.Relational.SqlSyntax: data Record c t
+ Database.Relational.SqlSyntax: data SetOp
+ Database.Relational.SqlSyntax: data SubQuery
+ Database.Relational.SqlSyntax: data WhenClauses
+ Database.Relational.SqlSyntax: except :: Duplication -> SubQuery -> SubQuery -> SubQuery
+ Database.Relational.SqlSyntax: flatSubQuery :: Config -> Tuple -> Duplication -> JoinProduct -> [Predicate Flat] -> [OrderingTerm] -> SubQuery
+ Database.Relational.SqlSyntax: growProduct :: Maybe (Node (DList (Predicate Flat))) -> (NodeAttr, Qualified SubQuery) -> Node (DList (Predicate Flat))
+ Database.Relational.SqlSyntax: intersect :: Duplication -> SubQuery -> SubQuery -> SubQuery
+ Database.Relational.SqlSyntax: newtype AggregateBitKey
+ Database.Relational.SqlSyntax: newtype AggregateKey a
+ Database.Relational.SqlSyntax: newtype AggregateSet
+ Database.Relational.SqlSyntax: newtype BinOp
+ Database.Relational.SqlSyntax: newtype Qualifier
+ Database.Relational.SqlSyntax: nodeAttr :: Node rs -> NodeAttr
+ Database.Relational.SqlSyntax: nodeTree :: Node rs -> ProductTree rs
+ Database.Relational.SqlSyntax: qualifier :: Qualified a -> Qualifier
+ Database.Relational.SqlSyntax: qualify :: Qualifier -> a -> Qualified a
+ Database.Relational.SqlSyntax: queryWidth :: Qualified SubQuery -> Int
+ Database.Relational.SqlSyntax: record :: Tuple -> Record c t
+ Database.Relational.SqlSyntax: recordRawColumns :: Record c r -> [StringSQL]
+ Database.Relational.SqlSyntax: recordWidth :: Record c r -> Int
+ Database.Relational.SqlSyntax: restrictProduct :: Node (DList (Predicate Flat)) -> Predicate Flat -> Node (DList (Predicate Flat))
+ Database.Relational.SqlSyntax: showSQL :: SubQuery -> StringSQL
+ Database.Relational.SqlSyntax: toSQL :: SubQuery -> String
+ Database.Relational.SqlSyntax: tupleFromJoinedSubQuery :: Qualified SubQuery -> Tuple
+ Database.Relational.SqlSyntax: tupleWidth :: Tuple -> Int
+ Database.Relational.SqlSyntax: type AggregateColumnRef = StringSQL
+ Database.Relational.SqlSyntax: type AssignColumn = StringSQL
+ Database.Relational.SqlSyntax: type AssignTerm = StringSQL
+ Database.Relational.SqlSyntax: type Assignment = (AssignColumn, AssignTerm)
+ Database.Relational.SqlSyntax: type JoinProduct = Maybe (ProductTree [Predicate Flat])
+ Database.Relational.SqlSyntax: type OrderColumn = StringSQL
+ Database.Relational.SqlSyntax: type OrderingTerm = ((Order, Maybe Nulls), OrderColumn)
+ Database.Relational.SqlSyntax: type PI c a b = Record c a -> Record c b
+ Database.Relational.SqlSyntax: type Predicate c = Record c (Maybe Bool)
+ Database.Relational.SqlSyntax: type Tuple = [Column]
+ Database.Relational.SqlSyntax: typeFromRawColumns :: [StringSQL] -> Record c r
+ Database.Relational.SqlSyntax: typeFromScalarSubQuery :: SubQuery -> Record c t
+ Database.Relational.SqlSyntax: unQualify :: Qualified a -> a
+ Database.Relational.SqlSyntax: union :: Duplication -> SubQuery -> SubQuery -> SubQuery
+ Database.Relational.SqlSyntax: unitSQL :: SubQuery -> String
+ Database.Relational.SqlSyntax: unsafeAggregateKey :: (a, AggregateElem) -> AggregateKey a
+ Database.Relational.SqlSyntax: untypeRecord :: Record c t -> Tuple
+ Database.Relational.SqlSyntax: width :: SubQuery -> Int
+ Database.Relational.TH: defineColumns :: ConName -> [((VarName, TypeQ), Maybe (TypeQ, VarName))] -> Q [Dec]
+ Database.Relational.TH: defineColumnsDefault :: ConName -> [((String, TypeQ), Maybe TypeQ)] -> Q [Dec]
+ Database.Relational.TH: defineHasNotNullKeyInstance :: TypeQ -> Int -> Q [Dec]
+ Database.Relational.TH: defineHasNotNullKeyInstanceWithConfig :: Config -> String -> String -> Int -> Q [Dec]
+ Database.Relational.TH: defineHasPrimaryKeyInstance :: TypeQ -> TypeQ -> [Int] -> Q [Dec]
+ Database.Relational.TH: defineHasPrimaryKeyInstanceWithConfig :: Config -> String -> String -> TypeQ -> [Int] -> Q [Dec]
+ Database.Relational.TH: definePrimaryQuery :: VarName -> TypeQ -> TypeQ -> ExpQ -> Q [Dec]
+ Database.Relational.TH: definePrimaryUpdate :: VarName -> TypeQ -> TypeQ -> ExpQ -> Q [Dec]
+ Database.Relational.TH: defineScalarDegree :: TypeQ -> Q [Dec]
+ Database.Relational.TH: defineSqlsWithPrimaryKey :: VarName -> VarName -> TypeQ -> TypeQ -> ExpQ -> ExpQ -> Q [Dec]
+ Database.Relational.TH: defineSqlsWithPrimaryKeyDefault :: String -> TypeQ -> TypeQ -> ExpQ -> ExpQ -> Q [Dec]
+ Database.Relational.TH: defineTable :: Config -> String -> String -> [(String, TypeQ)] -> [Name] -> [Int] -> Maybe Int -> Q [Dec]
+ Database.Relational.TH: defineTableTypes :: VarName -> VarName -> VarName -> VarName -> TypeQ -> String -> [String] -> Q [Dec]
+ Database.Relational.TH: defineTableTypesAndRecord :: Config -> String -> String -> [(String, TypeQ)] -> [Name] -> Q [Dec]
+ Database.Relational.TH: defineTableTypesWithConfig :: Config -> String -> String -> [((String, TypeQ), Maybe TypeQ)] -> Q [Dec]
+ Database.Relational.TH: defineTuplePi :: Int -> Q [Dec]
+ Database.Relational.TH: derivationExpDefault :: String -> ExpQ
+ Database.Relational.TH: inlineQuery :: Name -> Relation p r -> Config -> QuerySuffix -> String -> Q [Dec]
+ Database.Relational.TH: makeRelationalRecordDefault :: Name -> Q [Dec]
+ Database.Relational.TH: reifyRelation :: Name -> Q (Type, Type)
+ Database.Relational.TH: relationVarExp :: Config -> String -> String -> ExpQ
+ Database.Relational.TH: tableVarExpDefault :: String -> ExpQ
+ Database.Relational.TH: unsafeInlineQuery :: TypeQ -> TypeQ -> String -> VarName -> Q [Dec]
+ Database.Relational.Table: class PersistableWidth r => TableDerivable r
+ Database.Relational.Table: columns :: Table r -> [StringSQL]
+ Database.Relational.Table: data Table r
+ Database.Relational.Table: derivedTable :: TableDerivable r => Table r
+ Database.Relational.Table: index :: Table r -> Int -> StringSQL
+ Database.Relational.Table: name :: Table r -> String
+ Database.Relational.Table: recordWidth :: Table r -> PersistableRecordWidth r
+ Database.Relational.Table: shortName :: Table r -> String
+ Database.Relational.Table: table :: String -> [String] -> Table r
+ Database.Relational.Table: toMaybe :: Table r -> Table (Maybe r)
+ Database.Relational.Table: toSubQuery :: Table r -> SubQuery
+ Database.Relational.Table: unType :: Table t -> Untyped
+ Database.Relational.Table: width :: Table r -> Int
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2)
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.ProjectableClass.ShowConstantTermsSQL a3) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3)
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.ProjectableClass.ShowConstantTermsSQL a4) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4)
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.ProjectableClass.ShowConstantTermsSQL a5) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5)
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.ProjectableClass.ShowConstantTermsSQL a5, Database.Relational.ProjectableClass.ShowConstantTermsSQL a6) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5, a6)
+ Database.Relational.TupleInstances: instance (Database.Relational.ProjectableClass.ShowConstantTermsSQL a1, Database.Relational.ProjectableClass.ShowConstantTermsSQL a2, Database.Relational.ProjectableClass.ShowConstantTermsSQL a3, Database.Relational.ProjectableClass.ShowConstantTermsSQL a4, Database.Relational.ProjectableClass.ShowConstantTermsSQL a5, Database.Relational.ProjectableClass.ShowConstantTermsSQL a6, Database.Relational.ProjectableClass.ShowConstantTermsSQL a7) => Database.Relational.ProjectableClass.ShowConstantTermsSQL (a1, a2, a3, a4, a5, a6, a7)
+ Database.Relational.TupleInstances: tuplePi2_0' :: forall a1 a2. (PersistableWidth a1, PersistableWidth a2) => Pi (a1, a2) a1
+ Database.Relational.TupleInstances: tuplePi2_1' :: forall a1 a2. (PersistableWidth a1, PersistableWidth a2) => Pi (a1, a2) a2
+ Database.Relational.TupleInstances: tuplePi3_0' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a1
+ Database.Relational.TupleInstances: tuplePi3_1' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a2
+ Database.Relational.TupleInstances: tuplePi3_2' :: forall a1 a2 a3. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3) => Pi (a1, a2, a3) a3
+ Database.Relational.TupleInstances: tuplePi4_0' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a1
+ Database.Relational.TupleInstances: tuplePi4_1' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a2
+ Database.Relational.TupleInstances: tuplePi4_2' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a3
+ Database.Relational.TupleInstances: tuplePi4_3' :: forall a1 a2 a3 a4. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4) => Pi (a1, a2, a3, a4) a4
+ Database.Relational.TupleInstances: tuplePi5_0' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a1
+ Database.Relational.TupleInstances: tuplePi5_1' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a2
+ Database.Relational.TupleInstances: tuplePi5_2' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a3
+ Database.Relational.TupleInstances: tuplePi5_3' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a4
+ Database.Relational.TupleInstances: tuplePi5_4' :: forall a1 a2 a3 a4 a5. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5) => Pi (a1, a2, a3, a4, a5) a5
+ Database.Relational.TupleInstances: tuplePi6_0' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a1
+ Database.Relational.TupleInstances: tuplePi6_1' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a2
+ Database.Relational.TupleInstances: tuplePi6_2' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a3
+ Database.Relational.TupleInstances: tuplePi6_3' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a4
+ Database.Relational.TupleInstances: tuplePi6_4' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a5
+ Database.Relational.TupleInstances: tuplePi6_5' :: forall a1 a2 a3 a4 a5 a6. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6) => Pi (a1, a2, a3, a4, a5, a6) a6
+ Database.Relational.TupleInstances: tuplePi7_0' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a1
+ Database.Relational.TupleInstances: tuplePi7_1' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a2
+ Database.Relational.TupleInstances: tuplePi7_2' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a3
+ Database.Relational.TupleInstances: tuplePi7_3' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a4
+ Database.Relational.TupleInstances: tuplePi7_4' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a5
+ Database.Relational.TupleInstances: tuplePi7_5' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a6
+ Database.Relational.TupleInstances: tuplePi7_6' :: forall a1 a2 a3 a4 a5 a6 a7. (PersistableWidth a1, PersistableWidth a2, PersistableWidth a3, PersistableWidth a4, PersistableWidth a5, PersistableWidth a6, PersistableWidth a7) => Pi (a1, a2, a3, a4, a5, a6, a7) a7
+ Database.Relational.Type: Delete :: String -> Delete p
+ Database.Relational.Type: Insert :: String -> Maybe (String, Int) -> Insert a
+ Database.Relational.Type: InsertQuery :: String -> InsertQuery p
+ Database.Relational.Type: KeyUpdate :: Pi a p -> String -> KeyUpdate p a
+ Database.Relational.Type: Query :: String -> Query p a
+ Database.Relational.Type: Update :: String -> Update p
+ Database.Relational.Type: [chunkedInsert] :: Insert a -> Maybe (String, Int)
+ Database.Relational.Type: [untypeDelete] :: Delete p -> String
+ Database.Relational.Type: [untypeInsertQuery] :: InsertQuery p -> String
+ Database.Relational.Type: [untypeInsert] :: Insert a -> String
+ Database.Relational.Type: [untypeKeyUpdate] :: KeyUpdate p a -> String
+ Database.Relational.Type: [untypeQuery] :: Query p a -> String
+ Database.Relational.Type: [untypeUpdate] :: Update p -> String
+ Database.Relational.Type: [updateKey] :: KeyUpdate p a -> Pi a p
+ Database.Relational.Type: chunkSizeOfInsert :: Insert a -> Int
+ Database.Relational.Type: class UntypeableNoFetch s
+ Database.Relational.Type: data Insert a
+ Database.Relational.Type: data KeyUpdate p a
+ Database.Relational.Type: deleteSQL :: Config -> Table r -> Restriction p r -> String
+ Database.Relational.Type: derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p
+ Database.Relational.Type: derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p
+ Database.Relational.Type: derivedInsert :: (PersistableWidth r, TableDerivable r) => Pi r r' -> Insert r'
+ Database.Relational.Type: derivedInsertQuery :: TableDerivable r => Pi r r' -> Relation p r' -> InsertQuery p
+ Database.Relational.Type: derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p
+ Database.Relational.Type: derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p
+ Database.Relational.Type: derivedKeyUpdate :: TableDerivable r => Pi r p -> KeyUpdate p r
+ Database.Relational.Type: derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p
+ Database.Relational.Type: derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p
+ Database.Relational.Type: derivedUpdateAllColumn :: (PersistableWidth r, TableDerivable r) => RestrictedStatement r (PlaceHolders p) -> Update (r, p)
+ Database.Relational.Type: derivedUpdateAllColumn' :: (PersistableWidth r, TableDerivable r) => Config -> RestrictedStatement r (PlaceHolders p) -> Update (r, p)
+ Database.Relational.Type: insertQuerySQL :: Config -> Table r -> Pi r r' -> Relation p r' -> String
+ Database.Relational.Type: instance Database.Relational.Type.UntypeableNoFetch Database.Relational.Type.Delete
+ Database.Relational.Type: instance Database.Relational.Type.UntypeableNoFetch Database.Relational.Type.Insert
+ Database.Relational.Type: instance Database.Relational.Type.UntypeableNoFetch Database.Relational.Type.InsertQuery
+ Database.Relational.Type: instance Database.Relational.Type.UntypeableNoFetch Database.Relational.Type.Update
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.Delete p)
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.Insert a)
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.InsertQuery p)
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.KeyUpdate p a)
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.Query p a)
+ Database.Relational.Type: instance GHC.Show.Show (Database.Relational.Type.Update p)
+ Database.Relational.Type: newtype Delete p
+ Database.Relational.Type: newtype InsertQuery p
+ Database.Relational.Type: newtype Query p a
+ Database.Relational.Type: newtype Update p
+ Database.Relational.Type: relationalQuery :: Relation p r -> Query p r
+ Database.Relational.Type: relationalQuery' :: Relation p r -> QuerySuffix -> Query p r
+ Database.Relational.Type: relationalQuerySQL :: Config -> Relation p r -> QuerySuffix -> String
+ Database.Relational.Type: typedDelete :: Table r -> Restriction p r -> Delete p
+ Database.Relational.Type: typedDelete' :: Config -> Table r -> Restriction p r -> Delete p
+ Database.Relational.Type: typedInsert :: PersistableWidth r => Table r -> Pi r r' -> Insert r'
+ Database.Relational.Type: typedInsert' :: PersistableWidth r => Config -> Table r -> Pi r r' -> Insert r'
+ Database.Relational.Type: typedInsertQuery :: Table r -> Pi r r' -> Relation p r' -> InsertQuery p
+ Database.Relational.Type: typedInsertQuery' :: Config -> Table r -> Pi r r' -> Relation p r' -> InsertQuery p
+ Database.Relational.Type: typedInsertValue :: Table r -> InsertTarget p r -> Insert p
+ Database.Relational.Type: typedInsertValue' :: Config -> Table r -> InsertTarget p r -> Insert p
+ Database.Relational.Type: typedKeyUpdate :: Table a -> Pi a p -> KeyUpdate p a
+ Database.Relational.Type: typedKeyUpdateTable :: TableDerivable r => Relation () r -> Pi r p -> KeyUpdate p r
+ Database.Relational.Type: typedUpdate :: Table r -> UpdateTarget p r -> Update p
+ Database.Relational.Type: typedUpdate' :: Config -> Table r -> UpdateTarget p r -> Update p
+ Database.Relational.Type: typedUpdateAllColumn :: PersistableWidth r => Table r -> Restriction p r -> Update (r, p)
+ Database.Relational.Type: unsafeTypedDelete :: String -> Delete p
+ Database.Relational.Type: unsafeTypedInsert :: String -> Insert a
+ Database.Relational.Type: unsafeTypedInsert' :: String -> String -> Int -> Insert a
+ Database.Relational.Type: unsafeTypedInsertQuery :: String -> InsertQuery p
+ Database.Relational.Type: unsafeTypedKeyUpdate :: Pi a p -> String -> KeyUpdate p a
+ Database.Relational.Type: unsafeTypedQuery :: String -> Query p a
+ Database.Relational.Type: unsafeTypedUpdate :: String -> Update p
+ Database.Relational.Type: untypeChunkInsert :: Insert a -> String
+ Database.Relational.Type: untypeNoFetch :: UntypeableNoFetch s => s p -> String
+ Database.Relational.Type: updateSQL :: Config -> Table r -> UpdateTarget p r -> String
Files
- ChangeLog.md +4/−2
- relational-query.cabal +59/−49
- src/Database/Relational.hs +95/−0
- src/Database/Relational/Arrow.hs +447/−0
- src/Database/Relational/BaseTH.hs +76/−0
- src/Database/Relational/Compat.hs +121/−0
- src/Database/Relational/Config.hs +19/−0
- src/Database/Relational/Constraint.hs +113/−0
- src/Database/Relational/Context.hs +15/−0
- src/Database/Relational/Derives.hs +114/−0
- src/Database/Relational/Effect.hs +185/−0
- src/Database/Relational/Internal/Config.hs +74/−0
- src/Database/Relational/Internal/ContextType.hs +39/−0
- src/Database/Relational/Internal/String.hs +62/−0
- src/Database/Relational/Internal/UntypedTable.hs +44/−0
- src/Database/Relational/Monad/Aggregate.hs +103/−0
- src/Database/Relational/Monad/Assign.hs +48/−0
- src/Database/Relational/Monad/BaseType.hs +95/−0
- src/Database/Relational/Monad/Class.hs +94/−0
- src/Database/Relational/Monad/Register.hs +31/−0
- src/Database/Relational/Monad/Restrict.hs +46/−0
- src/Database/Relational/Monad/Simple.hs +67/−0
- src/Database/Relational/Monad/Trans/Aggregating.hs +170/−0
- src/Database/Relational/Monad/Trans/Assigning.hs +84/−0
- src/Database/Relational/Monad/Trans/Config.hs +41/−0
- src/Database/Relational/Monad/Trans/Join.hs +106/−0
- src/Database/Relational/Monad/Trans/JoinState.hs +45/−0
- src/Database/Relational/Monad/Trans/Ordering.hs +113/−0
- src/Database/Relational/Monad/Trans/Qualify.hs +54/−0
- src/Database/Relational/Monad/Trans/Restricting.hs +72/−0
- src/Database/Relational/Monad/Type.hs +37/−0
- src/Database/Relational/Monad/Unique.hs +59/−0
- src/Database/Relational/Pi.hs +42/−0
- src/Database/Relational/Pi/Unsafe.hs +182/−0
- src/Database/Relational/Projectable.hs +539/−0
- src/Database/Relational/ProjectableClass.hs +73/−0
- src/Database/Relational/ProjectableExtended.hs +168/−0
- src/Database/Relational/Pure.hs +160/−0
- src/Database/Relational/Query.hs +10/−85
- src/Database/Relational/Query/Arrow.hs +10/−439
- src/Database/Relational/Query/BaseTH.hs +0/−85
- src/Database/Relational/Query/Component.hs +0/−27
- src/Database/Relational/Query/Constraint.hs +0/−113
- src/Database/Relational/Query/Context.hs +0/−15
- src/Database/Relational/Query/Derives.hs +0/−113
- src/Database/Relational/Query/Effect.hs +0/−190
- src/Database/Relational/Query/Internal/BaseSQL.hs +0/−96
- src/Database/Relational/Query/Internal/Config.hs +0/−74
- src/Database/Relational/Query/Internal/ContextType.hs +0/−39
- src/Database/Relational/Query/Internal/GroupingSQL.hs +0/−119
- src/Database/Relational/Query/Internal/Product.hs +0/−53
- src/Database/Relational/Query/Internal/SQL.hs +0/−52
- src/Database/Relational/Query/Internal/Sub.hs +0/−204
- src/Database/Relational/Query/Internal/UntypedTable.hs +0/−44
- src/Database/Relational/Query/Monad/Aggregate.hs +0/−103
- src/Database/Relational/Query/Monad/Assign.hs +0/−49
- src/Database/Relational/Query/Monad/BaseType.hs +0/−95
- src/Database/Relational/Query/Monad/Class.hs +0/−95
- src/Database/Relational/Query/Monad/Register.hs +0/−31
- src/Database/Relational/Query/Monad/Restrict.hs +0/−47
- src/Database/Relational/Query/Monad/Simple.hs +0/−69
- src/Database/Relational/Query/Monad/Trans/Aggregating.hs +0/−169
- src/Database/Relational/Query/Monad/Trans/Assigning.hs +0/−85
- src/Database/Relational/Query/Monad/Trans/Config.hs +0/−41
- src/Database/Relational/Query/Monad/Trans/Join.hs +0/−106
- src/Database/Relational/Query/Monad/Trans/JoinState.hs +0/−42
- src/Database/Relational/Query/Monad/Trans/Ordering.hs +0/−122
- src/Database/Relational/Query/Monad/Trans/Qualify.hs +0/−54
- src/Database/Relational/Query/Monad/Trans/Restricting.hs +0/−71
- src/Database/Relational/Query/Monad/Type.hs +0/−38
- src/Database/Relational/Query/Monad/Unique.hs +0/−59
- src/Database/Relational/Query/Pi.hs +0/−42
- src/Database/Relational/Query/Pi/Unsafe.hs +0/−188
- src/Database/Relational/Query/Projectable.hs +0/−551
- src/Database/Relational/Query/ProjectableClass.hs +0/−102
- src/Database/Relational/Query/ProjectableExtended.hs +0/−201
- src/Database/Relational/Query/Projection.hs +0/−208
- src/Database/Relational/Query/Pure.hs +0/−162
- src/Database/Relational/Query/Relation.hs +0/−387
- src/Database/Relational/Query/SQL.hs +0/−118
- src/Database/Relational/Query/Scalar.hs +0/−32
- src/Database/Relational/Query/Sub.hs +0/−329
- src/Database/Relational/Query/TH.hs +0/−464
- src/Database/Relational/Query/Table.hs +0/−72
- src/Database/Relational/Query/TupleInstances.hs +0/−28
- src/Database/Relational/Query/Type.hs +0/−353
- src/Database/Relational/Record.hs +203/−0
- src/Database/Relational/Relation.hs +192/−0
- src/Database/Relational/Scalar.hs +32/−0
- src/Database/Relational/Set.hs +213/−0
- src/Database/Relational/SimpleSql.hs +106/−0
- src/Database/Relational/SqlSyntax.hs +25/−0
- src/Database/Relational/SqlSyntax/Aggregate.hs +94/−0
- src/Database/Relational/SqlSyntax/Fold.hs +270/−0
- src/Database/Relational/SqlSyntax/Join.hs +54/−0
- src/Database/Relational/SqlSyntax/Query.hs +114/−0
- src/Database/Relational/SqlSyntax/Types.hs +210/−0
- src/Database/Relational/SqlSyntax/Updates.hs +63/−0
- src/Database/Relational/TH.hs +475/−0
- src/Database/Relational/Table.hs +81/−0
- src/Database/Relational/TupleInstances.hs +27/−0
- src/Database/Relational/Type.hs +334/−0
- test/Model.hs +2/−2
- test/sqlsEq.hs +8/−7
- test/sqlsEqArrow.hs +8/−6
ChangeLog.md view
@@ -1,8 +1,10 @@ <!-- -*- Markdown -*- --> -## 0.9.5.1+## 0.10.0.0 -- add an upper bound of version constraint.+- switch namespace to Database.Relational+- update interfaces about projection types.+- divide and apply product-isomorphic interfaces. ## 0.9.5.0
relational-query.cabal view
@@ -1,5 +1,5 @@ name: relational-query-version: 0.9.5.1+version: 0.10.0.0 synopsis: Typeful, Modular, Relational, algebraic query engine description: This package contiains typeful relation structure and relational-algebraic query building DSL which can@@ -28,57 +28,64 @@ library exposed-modules:- Database.Relational.Query.Arrow+ Database.Relational.Arrow + Database.Relational+ Database.Relational.Table+ Database.Relational.SimpleSql+ Database.Relational.Pure+ Database.Relational.Pi+ Database.Relational.Pi.Unsafe+ Database.Relational.Constraint+ Database.Relational.Context+ Database.Relational.Config+ Database.Relational.SqlSyntax+ Database.Relational.Record+ Database.Relational.ProjectableClass+ Database.Relational.Projectable+ Database.Relational.ProjectableExtended+ Database.Relational.TupleInstances+ Database.Relational.Monad.BaseType+ Database.Relational.Monad.Class+ Database.Relational.Monad.Trans.Ordering+ Database.Relational.Monad.Trans.Aggregating+ Database.Relational.Monad.Trans.Restricting+ Database.Relational.Monad.Trans.Join+ Database.Relational.Monad.Trans.Config+ Database.Relational.Monad.Trans.Assigning+ Database.Relational.Monad.Type+ Database.Relational.Monad.Simple+ Database.Relational.Monad.Aggregate+ Database.Relational.Monad.Unique+ Database.Relational.Monad.Restrict+ Database.Relational.Monad.Assign+ Database.Relational.Monad.Register+ Database.Relational.Relation+ Database.Relational.Set+ Database.Relational.Effect+ Database.Relational.Scalar+ Database.Relational.Type+ Database.Relational.Derives+ Database.Relational.BaseTH+ Database.Relational.TH++ Database.Relational.Compat Database.Relational.Query- Database.Relational.Query.Table- Database.Relational.Query.SQL- Database.Relational.Query.Pure- Database.Relational.Query.Pi- Database.Relational.Query.Pi.Unsafe- Database.Relational.Query.Constraint- Database.Relational.Query.Context- Database.Relational.Query.Component- Database.Relational.Query.Sub- Database.Relational.Query.Projection- Database.Relational.Query.ProjectableClass- Database.Relational.Query.Projectable- Database.Relational.Query.ProjectableExtended- Database.Relational.Query.TupleInstances- Database.Relational.Query.Monad.BaseType- Database.Relational.Query.Monad.Class- Database.Relational.Query.Monad.Trans.Ordering- Database.Relational.Query.Monad.Trans.Aggregating- Database.Relational.Query.Monad.Trans.Restricting- Database.Relational.Query.Monad.Trans.Join- Database.Relational.Query.Monad.Trans.Config- Database.Relational.Query.Monad.Trans.Assigning- Database.Relational.Query.Monad.Type- Database.Relational.Query.Monad.Simple- Database.Relational.Query.Monad.Aggregate- Database.Relational.Query.Monad.Unique- Database.Relational.Query.Monad.Restrict- Database.Relational.Query.Monad.Assign- Database.Relational.Query.Monad.Register- Database.Relational.Query.Relation- Database.Relational.Query.Effect- Database.Relational.Query.Scalar- Database.Relational.Query.Type- Database.Relational.Query.Derives- Database.Relational.Query.BaseTH- Database.Relational.Query.TH+ Database.Relational.Query.Arrow other-modules:- Database.Relational.Query.Internal.Config- Database.Relational.Query.Internal.ContextType- Database.Relational.Query.Internal.SQL- Database.Relational.Query.Internal.BaseSQL- Database.Relational.Query.Internal.GroupingSQL- Database.Relational.Query.Internal.UntypedTable- Database.Relational.Query.Internal.Product- Database.Relational.Query.Internal.Sub- Database.Relational.Query.Monad.Trans.JoinState- Database.Relational.Query.Monad.Trans.Qualify+ Database.Relational.Internal.ContextType+ Database.Relational.Internal.Config+ Database.Relational.Internal.String+ Database.Relational.Internal.UntypedTable+ Database.Relational.SqlSyntax.Types+ Database.Relational.SqlSyntax.Join+ Database.Relational.SqlSyntax.Aggregate+ Database.Relational.SqlSyntax.Query+ Database.Relational.SqlSyntax.Fold+ Database.Relational.SqlSyntax.Updates+ Database.Relational.Monad.Trans.JoinState+ Database.Relational.Monad.Trans.Qualify build-depends: base <5 , array@@ -91,9 +98,10 @@ , dlist , template-haskell , th-reify-compat+ , product-isomorphic >= 0.0.3 , sql-words >=0.1.5 , names-th- , persistable-record >= 0.5.1 && < 0.6+ , persistable-record >= 0.6 if impl(ghc == 7.4.*) build-depends: ghc-prim == 0.2.* @@ -105,6 +113,7 @@ test-suite sqls build-depends: base <5 , quickcheck-simple+ , product-isomorphic , relational-query , containers , transformers@@ -125,6 +134,7 @@ test-suite sqlsArrow build-depends: base <5 , quickcheck-simple+ , product-isomorphic , relational-query , containers , transformers
+ src/Database/Relational.hs view
@@ -0,0 +1,95 @@+-- |+-- Module : Database.Relational+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module is integrated module of Query.+module Database.Relational (+ module Database.Relational.Table,+ module Database.Relational.SimpleSql,+ module Database.Relational.Pi,+ module Database.Relational.Constraint,+ module Database.Relational.Context,+ module Database.Relational.Config,+ module Database.Relational.SqlSyntax,+ module Database.Relational.Record,+ module Database.Relational.ProjectableClass,+ module Database.Relational.Projectable,+ module Database.Relational.ProjectableExtended,+ module Database.Relational.TupleInstances,+ module Database.Relational.Monad.BaseType,+ module Database.Relational.Monad.Class,+ module Database.Relational.Monad.Trans.Ordering,+ module Database.Relational.Monad.Trans.Aggregating,+ module Database.Relational.Monad.Trans.Assigning,+ module Database.Relational.Monad.Type,+ module Database.Relational.Monad.Simple,+ module Database.Relational.Monad.Aggregate,+ module Database.Relational.Monad.Restrict,+ module Database.Relational.Monad.Unique,+ module Database.Relational.Monad.Assign,+ module Database.Relational.Monad.Register,+ module Database.Relational.Relation,+ module Database.Relational.Set,+ module Database.Relational.Scalar,+ module Database.Relational.Type,+ module Database.Relational.Effect,+ module Database.Relational.Derives+ ) where++import Database.Relational.Table (Table, TableDerivable (..))+import Database.Relational.SimpleSql (QuerySuffix, updateOtherThanKeySQL)+import Database.Relational.Pure ()+import Database.Relational.Pi+import Database.Relational.Constraint+ (Key, tableConstraint, projectionKey,+ uniqueKey, -- notNullKey,+ HasConstraintKey(constraintKey),+ derivedUniqueKey, -- derivedNotNullKey,+ Primary, Unique, NotNull)+import Database.Relational.Context+import Database.Relational.Config+import Database.Relational.SqlSyntax+ (Order (..), Nulls (..), AggregateKey, Record, Predicate, PI,+ SubQuery, unitSQL, queryWidth, )+import Database.Relational.Record (RecordList, list)+import Database.Relational.ProjectableClass+import Database.Relational.Projectable+import Database.Relational.ProjectableExtended+import Database.Relational.TupleInstances+import Database.Relational.Monad.BaseType+import Database.Relational.Monad.Class+ (MonadQualify,+ MonadRestrict, wheres, having, restrict,+ MonadAggregate, groupBy, groupBy',+ MonadQuery, query', queryMaybe',+ MonadPartition, partitionBy,+ distinct, all', on)+import Database.Relational.Monad.Trans.Ordering (orderBy', orderBy, asc, desc)+import Database.Relational.Monad.Trans.Aggregating+ (key, key', set, bkey, rollup, cube, groupingSets)+import Database.Relational.Monad.Trans.Assigning (assignTo, (<-#))+import Database.Relational.Monad.Type+import Database.Relational.Monad.Simple (QuerySimple, SimpleQuery)+import Database.Relational.Monad.Aggregate+ (QueryAggregate, AggregatedQuery, Window, over)+import Database.Relational.Monad.Restrict (Restrict)+import Database.Relational.Monad.Unique (QueryUnique)+import Database.Relational.Monad.Assign (Assign)+import Database.Relational.Monad.Register (Register)+import Database.Relational.Relation+import Database.Relational.Set+import Database.Relational.Scalar (ScalarDegree)+import Database.Relational.Type hiding+ (unsafeTypedKeyUpdate, unsafeTypedDelete,+ unsafeTypedInsert, unsafeTypedInsertQuery, )+import Database.Relational.Effect+import Database.Relational.Derives++import Database.Record.Instances ()++{-# ANN module "HLint: ignore Use import/export shortcut" #-}
+ src/Database/Relational/Arrow.hs view
@@ -0,0 +1,447 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- |+-- Module : Database.Relational.Arrow+-- Copyright : 2015-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines arrow version combinators which+-- improves type-safty on building queries.+-- Referencing the local projected records may cause to break+-- the result query.+-- It is possible to controls injection of previous local projected records+-- by restricting domain type of arrow. This idea is imported from Opaleye:+--+-- * <https://github.com/tomjaguarpaw/haskell-opaleye>+-- * <https://github.com/khibino/haskell-relational-record/issues/19>+--+-- Importing this module instead of "Database.Relational.Query" enables+-- to build query using arrow combinators.+module Database.Relational.Arrow (+ module Database.Relational,++ all', distinct,++ query, queryMaybe, query', queryMaybe',+ queryList, queryList', queryExists, queryExists', queryListU, queryListU',+ queryScalar, queryScalar', queryScalarU, queryScalarU',++ uniqueQuery', uniqueQueryMaybe',++ on, wheres, having, groupBy, placeholder,++ relation, relation', aggregateRelation, aggregateRelation',++ uniqueRelation',++ groupBy', key, key', set, bkey, rollup, cube, groupingSets,++ orderBy', orderBy, asc, desc,++ partitionBy, over,++ assign,++ derivedUpdate', derivedUpdate,+ derivedInsertValue', derivedInsertValue,+ derivedDelete', derivedDelete,++ QueryA,++ QuerySimple, QueryAggregate, QueryUnique,++ AggregatingSet, AggregatingSetList, AggregatingPowerSet,++ Orderings, Window, Assignings,++ AssignStatement, Register, RestrictedStatement,+ ) where++import Control.Category (Category)+import Control.Arrow (Arrow, Kleisli (..))++import Database.Record++import Database.Relational hiding+ (all', distinct,+ query, queryMaybe, query', queryMaybe',+ queryList, queryList', queryScalar, queryScalar',+ uniqueQuery', uniqueQueryMaybe',+ on, wheres, having, groupBy, placeholder,+ relation, relation', aggregateRelation, aggregateRelation', uniqueRelation',+ groupBy', key, key', set, bkey, rollup, cube, groupingSets,+ orderBy', orderBy, asc, desc, partitionBy, over,+ derivedUpdate', derivedUpdate,+ derivedInsertValue', derivedInsertValue,+ derivedDelete', derivedDelete,+ QuerySimple, QueryAggregate, QueryUnique, Window, Register)+import qualified Database.Relational as Monadic+import qualified Database.Relational.Monad.Trans.Aggregating as Monadic+import qualified Database.Relational.Monad.Trans.Ordering as Monadic+import qualified Database.Relational.Monad.Trans.Assigning as Monadic+++-- | Arrow to build queries.+newtype QueryA m a b = QueryA (Kleisli m a b) deriving (Category, Arrow)++queryA :: (a -> m b) -> QueryA m a b+queryA = QueryA . Kleisli++runQueryA :: QueryA m a b -> a -> m b+runQueryA (QueryA k) = runKleisli k++runAofM :: (m b -> c) -> QueryA m () b -> c+runAofM = (. (`runQueryA` ()))++-- | Arrow type corresponding to 'Monadic.QuerySimple'+type QuerySimple = QueryA Monadic.QuerySimple++-- | Arrow type corresponding to 'Monadic.QueryAggregate'+type QueryAggregate = QueryA Monadic.QueryAggregate++-- | Arrow type corresponding to 'Monadic.QueryUnique'+type QueryUnique = QueryA Monadic.QueryUnique++-- | Arrow type corresponding to 'Monadic.AggregatingSet'+type AggregatingSet = QueryA Monadic.AggregatingSet++-- | Arrow type corresponding to 'Monadic.AggregatingSetList'+type AggregatingSetList = QueryA Monadic.AggregatingSetList++-- | Arrow type corresponding to 'Monadic.AggregatingPowerSet'+type AggregatingPowerSet = QueryA Monadic.AggregatingPowerSet++-- | Arrow type corresponding to 'Monadic.Orderings'+type Orderings c m = QueryA (Monadic.Orderings c m)++-- | Arrow type corresponding to 'Monadic.Window'+type Window c = QueryA (Monadic.Window c)++-- | Arrow type corresponding to 'Monadic.Assignings'+type Assignings r m = QueryA (Monadic.Assignings r m)++-- | Arrow type corresponding to 'Monadic.AssignStatement'+type AssignStatement r a = Assignings r Restrict (Record Flat r) a++-- | Arrow type corresponding to 'Monadic.Register'+type Register r a = QueryA (Monadic.Register r) () a++-- | Arrow type corresponding to 'Monadic.RestrictedStatement'+type RestrictedStatement r a = QueryA Monadic.Restrict (Record Flat r) a+++-- | Same as 'Monadic.all''. Arrow version.+all' :: MonadQuery m => QueryA m () ()+all' = queryA $ \() -> Monadic.all'++-- | Same as 'Monadic.distinct'. Arrow version.+distinct :: MonadQuery m => QueryA m () ()+distinct = queryA $ \() -> Monadic.distinct++-- | Same as 'Monadic.query'. Arrow version.+-- The result arrow is not injected by local projected records.+query :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation () r -> QueryA m () (Record Flat r)+query r = queryA $ \() -> Monadic.query r++-- | Same as 'Monadic.queryMaybe'. Arrow version.+-- The result arrow is not injected by any local projected records.+queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation () r -> QueryA m () (Record Flat (Maybe r))+queryMaybe r = queryA $ \() -> Monadic.queryMaybe r++-- | Same as 'Monadic.query''. Arrow version.+-- The result arrow is not injected by any local projected records.+query' :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation p r -> QueryA m () (PlaceHolders p, Record Flat r)+query' r = queryA $ \() -> Monadic.query' r++-- | Same as 'Monadic.queryMaybe''. Arrow version.+-- The result arrow is not injected by any local projected records.+queryMaybe' :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation p r -> QueryA m () (PlaceHolders p, Record Flat (Maybe r))+queryMaybe' r = queryA $ \() -> Monadic.queryMaybe' r++unsafeQueryList :: MonadQualify ConfigureQuery m+ => (a -> Relation () r)+ -> QueryA m a (RecordList (Record c) r)+unsafeQueryList rf = queryA $ Monadic.queryList . rf++unsafeQueryList' :: MonadQualify ConfigureQuery m+ => (a -> Relation p r)+ -> QueryA m a (PlaceHolders p, RecordList (Record c) r)+unsafeQueryList' rf = queryA $ Monadic.queryList' . rf++-- | Same as 'Monadic.queryList'. Arrow version.+-- The result arrow is designed to be injected by local projected records.+queryList :: MonadQualify ConfigureQuery m+ => (Record c a -> Relation () r)+ -> QueryA m (Record c a) (RecordList (Record c) r)+queryList = unsafeQueryList++-- | Same as 'Monadic.queryList''. Arrow version.+-- The result arrow is designed to be injected by local projected records.+queryList' :: MonadQualify ConfigureQuery m+ => (Record c a -> Relation p r)+ -> QueryA m (Record c a) (PlaceHolders p, RecordList (Record c) r)+queryList' = unsafeQueryList'++-- | Same as 'Monadic.queryList' to pass this result to 'exists' operator. Arrow version.+-- The result arrow is designed to be injected by local projected records.+queryExists :: MonadQualify ConfigureQuery m+ => (Record c a -> Relation () r)+ -> QueryA m (Record c a) (RecordList (Record Exists) r)+queryExists = unsafeQueryList++-- | Same as 'Monadic.queryList'' to pass this result to 'exists' operator. Arrow version.+-- The result arrow is designed to be injected by local projected records.+queryExists' :: MonadQualify ConfigureQuery m+ => (Record c a -> Relation p r)+ -> QueryA m (Record c a) (PlaceHolders p, RecordList (Record Exists) r)+queryExists' = unsafeQueryList'++-- | Same as 'Monadic.queryList'. Arrow version.+-- Useful for no reference cases to local projected records.+queryListU :: MonadQualify ConfigureQuery m+ => Relation () r+ -> QueryA m () (RecordList (Record c) r)+queryListU r = unsafeQueryList $ \() -> r++-- | Same as 'Monadic.queryList''. Arrow version.+-- Useful for no reference cases to local projected records.+queryListU' :: MonadQualify ConfigureQuery m+ => Relation p r+ -> QueryA m () (PlaceHolders p, RecordList (Record c) r)+queryListU' r = unsafeQueryList' $ \() -> r++unsafeQueryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => (a -> UniqueRelation () c r)+ -> QueryA m a (Record c (Maybe r))+unsafeQueryScalar rf = queryA $ Monadic.queryScalar . rf++unsafeQueryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => (a -> UniqueRelation p c r)+ -> QueryA m a (PlaceHolders p, Record c (Maybe r))+unsafeQueryScalar' rf = queryA $ Monadic.queryScalar' . rf++-- | Same as 'Monadic.queryScalar'. Arrow version.+-- The result arrow is designed to be injected by any local projected record.+queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => (Record c a -> UniqueRelation () c r)+ -> QueryA m (Record c a) (Record c (Maybe r))+queryScalar = unsafeQueryScalar++-- | Same as 'Monadic.queryScalar''. Arrow version.+-- The result arrow is designed to be injected by any local projected record.+queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => (Record c a -> UniqueRelation p c r)+ -> QueryA m (Record c a) (PlaceHolders p, Record c (Maybe r))+queryScalar' = unsafeQueryScalar'++-- | Same as 'Monadic.queryScalar'. Arrow version.+-- Useful for no reference cases to local projected records.+queryScalarU :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => UniqueRelation () c r+ -> QueryA m () (Record c (Maybe r))+queryScalarU r = unsafeQueryScalar $ \() -> r++-- | Same as 'Monadic.queryScalar''. Arrow version.+-- Useful for no reference cases to local projected records.+queryScalarU' :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => UniqueRelation p c r+ -> QueryA m () (PlaceHolders p, Record c (Maybe r))+queryScalarU' r = unsafeQueryScalar' $ \() -> r++-- | Same as 'Monadic.uniqueQuery''. Arrow version.+-- The result arrow is not injected by local projected records.+uniqueQuery' :: UniqueRelation p c r+ -> QueryA Monadic.QueryUnique () (PlaceHolders p, Record c r)+uniqueQuery' r = queryA $ \() -> Monadic.uniqueQuery' r++-- | Same as 'Monadic.uniqueQueryMaybe''. Arrow version.+-- The result arrow is not injected by local projected records.+uniqueQueryMaybe' :: UniqueRelation p c r+ -> QueryA Monadic.QueryUnique () (PlaceHolders p, Record c (Maybe r))+uniqueQueryMaybe' r = queryA $ \() -> Monadic.uniqueQueryMaybe' r++-- | Same as 'Monadic.on'. Arrow version.+-- The result arrow is designed to be injected by local conditional flat-records.+on :: MonadQuery m+ => QueryA m (Predicate Flat) ()+on = queryA Monadic.on++-- | Same as 'Monadic.wheres'. Arrow version.+-- The result arrow is designed to be injected by local conditional flat-records.+wheres :: MonadRestrict Flat m+ => QueryA m (Predicate Flat) ()+wheres = queryA Monadic.wheres++-- | Same as 'Monadic.having'. Arrow version.+-- The result arrow is designed to be injected by local conditional aggregated-records.+having :: MonadRestrict Aggregated m+ => QueryA m (Predicate Aggregated) ()+having = queryA Monadic.having++-- | Same as 'Monadic.groupBy'. Arrow version.+-- The result arrow is designed to be injected by local flat-records.+groupBy :: MonadAggregate m+ => QueryA m (Record Flat r) (Record Aggregated r)+groupBy = queryA Monadic.groupBy++-- | Same as 'Monadic.placeholder'. Arrow version.+-- The result arrow is designed to be injected by locally built arrow using placeholders.+placeholder :: (PersistableWidth t, SqlContext c, Monad m)+ => QueryA m (QueryA m (Record c t) a) (PlaceHolders t, a)+placeholder = queryA $ Monadic.placeholder . runQueryA++-- | Same as 'Monadic.relation'.+-- Finalize query-building arrow instead of query-building monad.+relation :: QuerySimple () (Record Flat r)+ -> Relation () r+relation = runAofM Monadic.relation++-- | Same as 'Monadic.relation''.+-- Finalize query-building arrow instead of query-building monad.+relation' :: QuerySimple () (PlaceHolders p, Record Flat r)+ -> Relation p r+relation' = runAofM Monadic.relation'++-- | Same as 'Monadic.aggregateRelation'.+-- Finalize query-building arrow instead of query-building monad.+aggregateRelation :: QueryAggregate () (Record Aggregated r)+ -> Relation () r+aggregateRelation = runAofM Monadic.aggregateRelation++-- | Same as 'Monadic.aggregateRelation''.+-- Finalize query-building arrow instead of query-building monad.+aggregateRelation' :: QueryAggregate () (PlaceHolders p, Record Aggregated r)+ -> Relation p r+aggregateRelation' = runAofM Monadic.aggregateRelation'++-- | Same as 'Monadic.uniqueRelation''.+-- Finalize query-building arrow instead of query-building monad.+uniqueRelation' :: QueryUnique () (PlaceHolders p, Record c r)+ -> UniqueRelation p c r+uniqueRelation' = runAofM Monadic.uniqueRelation'++-- | Same as 'Monadic.groupBy''.+-- This arrow is designed to be injected by local 'AggregateKey'.+groupBy' :: MonadAggregate m => QueryA m (AggregateKey (Record Aggregated r)) (Record Aggregated r)+groupBy' = queryA Monadic.groupBy'++-- | Same as 'Monadic.key'.+-- This arrow is designed to be injected by local flat-records.+key :: AggregatingSet (Record Flat r) (Record Aggregated (Maybe r))+key = queryA Monadic.key++-- | Same as 'Monadic.key''.+-- This arrow is designed to be injected by local 'AggregteKey'.+key' :: AggregatingSet (AggregateKey a) a+key' = queryA Monadic.key'++-- | Same as 'Monadic.set'.+-- This arrow is designed to be injected by locally built 'AggregtingSet' arrow.+set :: AggregatingSetList (AggregatingSet () a) a+set = queryA $ runAofM Monadic.set++-- | Same as 'Monadic.bkey'.+-- This arrow is designed to be injected by local flat-records.+bkey :: AggregatingPowerSet (Record Flat r) (Record Aggregated (Maybe r))+bkey = queryA Monadic.bkey++-- | Same as 'Monadic.rollup'.+-- Finalize locally built 'AggregatingPowerSet'.+rollup :: AggregatingPowerSet () a -> AggregateKey a+rollup = runAofM Monadic.rollup++-- | Same as 'Monadic.cube'.+-- Finalize locally built 'AggregatingPowerSet'.+cube :: AggregatingPowerSet () a -> AggregateKey a+cube = runAofM Monadic.cube++-- | Same as 'Monadic.groupingSets'.+-- Finalize locally built 'AggregatingSetList'.+groupingSets :: AggregatingSetList () a -> AggregateKey a+groupingSets = runAofM Monadic.groupingSets++-- | Same as 'Monadic.orderBy''.+-- The result arrow is designed to be injected by local projected records.+orderBy' :: Monad m+ => Order+ -> Nulls+ -> Orderings c m (Record c t) ()+orderBy' o n = queryA $ \p -> Monadic.orderBy' p o n++-- | Same as 'Monadic.orderBy'.+-- The result arrow is designed to be injected by local projected records.+orderBy :: Monad m+ => Order+ -> Orderings c m (Record c t) ()+orderBy o = queryA (`Monadic.orderBy` o)++-- | Same as 'Monadic.asc'.+-- The result arrow is designed to be injected by local projected records.+asc :: Monad m+ => Orderings c m (Record c t) ()+asc = queryA Monadic.asc++-- | Same as 'Monadic.desc'.+-- The result arrow is designed to be injected by local projected records.+desc :: Monad m+ => Orderings c m (Record c t) ()+desc = queryA Monadic.desc++-- | Same as 'Monadic.partitionBy'.+-- The result arrow is designed to be injected by local projected records.+partitionBy :: Window c (Record c r) ()+partitionBy = queryA Monadic.partitionBy++-- | Same as 'Monadic.over'.+-- Make record of window function result using built 'Window' arrow.+over :: SqlContext c+ => Record OverWindow a -> Window c () () -> Record c a+over po = runAofM $ Monadic.over po++infix 8 `over`++-- | Make 'Monadic.AssignTarget' into arrow which is designed to be+-- injected by assignees of local projected record.+assign :: Monad m+ => Monadic.AssignTarget r v+ -> Assignings r m (Record Flat v) ()+assign t = queryA (`Monadic.assignTo` t)++-- | Same as 'Monadic.derivedUpdate''.+-- Make 'Update' from assigning statement arrow using configuration.+derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p+derivedUpdate' config = Monadic.derivedUpdate' config . runQueryA++-- | Same as 'Monadic.derivedUpdate'.+-- Make 'Update' from assigning statement arrow.+derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p+derivedUpdate = Monadic.derivedUpdate . runQueryA++-- | Same as 'Monadic.derivedInsertValue''.+-- Make 'Insert' from register arrow using configuration.+derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p+derivedInsertValue' config = Monadic.derivedInsertValue' config . ($ ()) . runQueryA++-- | Same as 'Monadic.derivedInsertValue'.+-- Make 'Insert' from register arrow.+derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p+derivedInsertValue = Monadic.derivedInsertValue . ($ ()) . runQueryA++-- | Same as 'Monadic.derivedDelete''.+-- Make 'Update' from restrict statement arrow using configuration.+derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p+derivedDelete' config = Monadic.derivedDelete' config . runQueryA++-- | Same as 'Monadic.derivedDelete'.+-- Make 'Update' from restrict statement arrow.+derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p+derivedDelete = Monadic.derivedDelete . runQueryA
+ src/Database/Relational/BaseTH.hs view
@@ -0,0 +1,76 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}++-- |+-- Module : Database.Relational.BaseTH+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines templates for internally using.+module Database.Relational.BaseTH (+ defineTupleShowConstantInstance,+ defineTuplePi,++ defineRecordProjections,+ ) where++import Control.Applicative ((<$>))+import Data.List (foldl', inits)+import Language.Haskell.TH+ (Q, Name, mkName, normalB, classP, varP,+ TypeQ, forallT, varT, tupleT, appT,+ Dec, sigD, valD, instanceD,+ TyVarBndr (PlainTV), )+import Database.Record.Persistable+ (PersistableWidth, persistableWidth,+ PersistableRecordWidth, runPersistableRecordWidth)++import Database.Relational.ProjectableClass (ShowConstantTermsSQL (..))+import Database.Relational.Pi.Unsafe (Pi, definePi)+++tupleN :: Int -> (([Name], [TypeQ]), TypeQ)+tupleN n = ((ns, vs), foldl' appT (tupleT n) vs)+ where+ ns = [ mkName $ "a" ++ show j | j <- [1 .. n] ]+ vs = map varT ns++-- | Make template of 'ShowConstantTermsSQL' instance of tuple type.+defineTupleShowConstantInstance :: Int -> Q [Dec]+defineTupleShowConstantInstance n = do+ let ((_, vs), tty) = tupleN n+ (:[]) <$> instanceD+ -- in template-haskell 2.8 or older, Pred is not Type+ (mapM (classP ''ShowConstantTermsSQL . (:[])) vs)+ [t| ShowConstantTermsSQL $tty |]+ []++-- | Make polymorphic projection templates.+defineRecordProjections :: TypeQ -> [Name] -> [Name] -> [TypeQ] -> Q [Dec]+defineRecordProjections tyRec avs sels cts =+ fmap concat . sequence $ zipWith3 template cts (inits cts) sels+ where+ template :: TypeQ -> [TypeQ] -> Name -> Q [Dec]+ template ct pcts selN = do+ sig <- sigD selN $+ forallT (map PlainTV avs)+ (mapM (classP ''PersistableWidth . (:[]) . varT) avs)+ [t| Pi $tyRec $ct |]+ let runPW t = [| runPersistableRecordWidth (persistableWidth :: PersistableRecordWidth $t) |]+ val <- valD (varP selN)+ (normalB [| definePi $(foldl' (\e t -> [| $e + $(runPW t) |]) [| 0 :: Int |] pcts) |]) []+ return [sig, val]++-- | Make templates of projection paths for tuple types.+defineTuplePi :: Int -> Q [Dec]+defineTuplePi n =+ defineRecordProjections tyRec avs sels cts+ where+ ((avs, cts), tyRec) = tupleN n+ sels = [ mkName $ "tuplePi" ++ show n ++ "_" ++ show i ++ "'"+ | i <- [ 0 .. n - 1] ]
+ src/Database/Relational/Compat.hs view
@@ -0,0 +1,121 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ConstraintKinds #-}+{-# LANGUAGE KindSignatures #-}++-- |+-- Module : Database.Relational.Compat+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains backward compatibility definitions of+-- relational-query <= 0.9.*+module Database.Relational.Compat+ {-# DEPRECATED "backward compatibility definitions relational-query <= 0.9.*" #-} (+ -- * deprecated types+ Projection, ListProjection,++ -- * deprecated classes+ ProductConstructor (..),+ ProjectableFunctor, (|$|), ProjectableApplicative, (|*|),++ ProjectableIdZip, rightId, leftId,++ SqlProjectable (..), unsafeProjectSql,+ ProjectableShowSql (..), unsafeShowSql,++ -- * deprecated defintions about Pi+ pfmap, pap, pzero,+ ) where++import Data.Functor.ProductIsomorphic+ (ProductIsoFunctor, (|$|), ProductIsoApplicative, (|*|),+ ProductIsoEmpty, pureE, peRight, peLeft, )+import Data.Functor.ProductIsomorphic.Unsafe (ProductConstructor (..))++import Database.Relational hiding (unsafeShowSql', unsafeShowSql, unsafeProjectSqlTerms, unsafeProjectSql, )+import Database.Relational.Internal.String (showStringSQL, stringSQL)+import qualified Database.Relational.Record as Record+import qualified Database.Relational.Projectable as Projectable++{-# DEPRECATED Projection "Replaced by Record type" #-}+-- | deprecated 'Projection' type replaced by 'Record' type.+type Projection = Record++{-# DEPRECATED ListProjection "Replaced by RecordList type" #-}+-- | deprecated 'Projection' type replaced by 'Record' type.+type ListProjection = RecordList++{-# DEPRECATED ProjectableFunctor "use ProductIsoFunctor in Data.Functor.ProductIsomorphic instead of this. " #-}+-- | deprecated 'ProjectableFunctor' class replaced by 'ProductIsoFunctor' class.+type ProjectableFunctor = ProductIsoFunctor++{-# DEPRECATED ProjectableApplicative "use ProductIsoApplicative in Data.Functor.ProductIsomorphic instead of this. " #-}+-- | deprecated 'ProjectableApplicative' class replaced by 'ProductIsoApplicative' class.+type ProjectableApplicative = ProductIsoApplicative++{-# DEPRECATED ProjectableIdZip "use ProductIsoEmpty in Data.Functor.ProductIsomorphic instead of this. " #-}+-- | deprecated 'ProjectableIdZip' class replaced by 'ProductIsoEmpty' class.+type ProjectableIdZip p = ProductIsoEmpty p ()++{-# DEPRECATED rightId "use peRight in Data.Functor.ProductIsomorphic instead of this. " #-}+-- | deprecated right-id-law definition replaced by 'peRight'+rightId :: ProjectableIdZip p => p (a, ()) -> p a+rightId = peRight++{-# DEPRECATED leftId "use peLeft in Data.Functor.ProductIsomorphic instead of this. " #-}+-- | deprecated left-id-law definition replaced by 'peLeft'+leftId :: ProjectableIdZip p => p ((), a) -> p a+leftId = peLeft++-- Pi++{-# DEPRECATED pfmap "use (|$|) in Data.Functor.ProductIsomorphic instead of this." #-}+-- | deprecated map definition for Pi type. use ('|$|') instead of this.+pfmap :: ProductConstructor (a -> b) => (a -> b) -> Pi r a -> Pi r b+pfmap = (|$|)++{-# DEPRECATED pap "use (|*|) in Data.Functor.ProductIsomorphic instead of this." #-}+-- | deprecated ap definition for Pi type. use ('|*|') instead of this.+pap :: Pi r (a -> b) -> Pi r a -> Pi r b+pap = (|*|)++{-# DEPRECATED pzero "use pureE in Data.Functor.ProductIsomorphic instead of this." #-}+-- | deprecated empty definition for Pi type. use 'pureE' instead of this.+pzero :: Pi a ()+pzero = pureE++-- type classes++{-# DEPRECATED SqlProjectable "use 'SqlContext c => Record c a' instead of 'SqlProjectable p => p a'." #-}+-- | Interface to project SQL terms unsafely.+class SqlProjectable p where+ -- | Unsafely project from SQL expression terms.+ unsafeProjectSqlTerms :: [StringSQL] -- ^ SQL expression strings+ -> p t -- ^ Result record+{-# DEPRECATED unsafeProjectSqlTerms "Use Database.Relational.unsafeProjectSqlTerms instead of this." #-}++-- | Unsafely make 'Record' from SQL terms.+instance SqlContext c => SqlProjectable (Record c) where+ unsafeProjectSqlTerms = Projectable.unsafeProjectSqlTerms++{-# DEPRECATED unsafeProjectSql "Use Database.Relational.unsafeProjectSql instead of this." #-}+unsafeProjectSql :: SqlProjectable p => String -> p a+unsafeProjectSql = unsafeProjectSqlTerms . (:[]) . stringSQL++{-# DEPRECATED ProjectableShowSql "specialized type 'Record c' should be used instead of this constraint." #-}+-- | Interface to get SQL expression from a record.+class ProjectableShowSql p where+ unsafeShowSql' :: p a -> StringSQL+{-# DEPRECATED unsafeShowSql' "Use Database.Relational.unsafeShowSql' instead of this." #-}++instance ProjectableShowSql (Record c) where+ unsafeShowSql' = Record.unsafeStringSql++{-# DEPRECATED unsafeShowSql "Use Database.Relational.unsafeShowSql instead of this." #-}+unsafeShowSql :: ProjectableShowSql p => p a -> String+unsafeShowSql = showStringSQL . unsafeShowSql'
+ src/Database/Relational/Config.hs view
@@ -0,0 +1,19 @@+-- |+-- Module : Database.Relational.Config+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides untyped components for query.+module Database.Relational.Config+ ( -- * Configuration type for query+ module Database.Relational.Internal.Config,+ ) where++import Database.Relational.Internal.Config+ (NameConfig (..),+ ProductUnitSupport (..), SchemaNameMode (..), IdentifierQuotation (..),+ Config (..), defaultConfig,)
+ src/Database/Relational/Constraint.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Module : Database.Relational.Constraint+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides proof object definitions of constraint key.+-- Difference between this module and "Database.Record.KeyConstraint" is+-- typed constraint key column definition is included in this module.+module Database.Relational.Constraint (+ -- * Constraint Key proof object+ Key, indexes, unsafeDefineConstraintKey,+ tableConstraint, projectionKey,++ -- unsafeReturnKey, -- unsafeAppendConstraint,++ -- * Derivation rules+ uniqueKey, -- notNullKey,++ -- * Inference rules+ HasConstraintKey (..),+ derivedUniqueKey, -- derivedNotNullKey,++ -- * Constraint types+ Primary, Unique, NotNull+ ) where+++import Database.Record (PersistableRecordWidth, PersistableWidth (persistableWidth))+import Database.Record.KeyConstraint+ (KeyConstraint, unsafeSpecifyKeyConstraint,+ Primary, Unique, NotNull)+import qualified Database.Record.KeyConstraint as C++import Database.Relational.Pi (Pi)+import qualified Database.Relational.Pi.Unsafe as UnsafePi+++-- | Constraint Key proof object. Constraint type 'c', record type 'r' and columns type 'ct'.+data Key c r ct = Key [Int] (PersistableRecordWidth ct)++-- | Index of key which specifies constraint key.+indexes :: Key c r ct -> [Int]+indexes (Key is _) = is++-- | Width of key.+width :: Key c r ct -> PersistableRecordWidth ct+width (Key _ w) = w++-- | Unsafely generate constraint 'Key' proof object using specified key index.+unsafeDefineConstraintKey :: PersistableWidth ct+ => [Int] -- ^ Key indexes which specify this constraint key+ -> Key c r ct -- ^ Result constraint key proof object+unsafeDefineConstraintKey ixs = Key ixs persistableWidth++-- | Get table constraint 'KeyConstraint' proof object from constraint 'Key'.+tableConstraint :: Key c r ct -> KeyConstraint c r+tableConstraint = unsafeSpecifyKeyConstraint . indexes++-- | Get projection path proof object from constraint 'Key'.+projectionKey :: Key c r ct -> Pi r ct+projectionKey k = UnsafePi.defineDirectPi' w ixs where+ ixs = indexes k+ w = width k++-- | Unsafe. Make constraint key to add column phantom type+unsafeReturnKey :: PersistableWidth ct+ => KeyConstraint c r -> Key c r ct+unsafeReturnKey = unsafeDefineConstraintKey . C.indexes++-- -- | Unsafe. Make constraint key to add constraint phantom type+-- unsafeAppendConstraint :: Pi r ct -> Key c r ct+-- unsafeAppendConstraint = unsafeDefineConstraintKey . leafIndex+++-- | Map from table constraint into constraint 'Key'.+mapConstraint :: PersistableWidth ct+ => (KeyConstraint c0 r -> KeyConstraint c1 r)+ -> Key c0 r ct+ -> Key c1 r ct+mapConstraint f = unsafeReturnKey . f . tableConstraint++-- | Derive 'Unique' constraint 'Key' from 'Primary' constraint 'Key'+uniqueKey :: PersistableWidth ct+ => Key Primary r ct -> Key Unique r ct+uniqueKey = mapConstraint C.unique++-- -- | Derive 'NotNull' constraint 'Key' from 'Primary' constraint 'Key'+-- notNullKey :: Key Primary r ct -> Key NotNull r ct+-- notNullKey = mapConstraint C.notNull+++-- | Constraint 'Key' inference interface.+class PersistableWidth ct => HasConstraintKey c r ct where+ -- | Infer constraint key.+ constraintKey :: Key c r ct++-- | Inferred 'Unique' constraint 'Key'.+-- Record type 'r' has unique key which type is 'ct' derived from primay key.+derivedUniqueKey :: HasConstraintKey Primary r ct => Key Unique r ct+derivedUniqueKey = uniqueKey constraintKey++-- -- | Inferred 'NotNull' constraint 'Key'.+-- -- Record type 'r' has not-null key which type is 'ct' derived from primay key.+-- derivedNotNullKey :: HasConstraintKey Primary r ct => Key NotNull r ct+-- derivedNotNullKey = notNullKey constraintKey
+ src/Database/Relational/Context.hs view
@@ -0,0 +1,15 @@+-- |+-- Module : Database.Relational.Context+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module re-export query context tag types.+module Database.Relational.Context+ ( module Database.Relational.Internal.ContextType+ ) where++import Database.Relational.Internal.ContextType
+ src/Database/Relational/Derives.hs view
@@ -0,0 +1,114 @@+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Module : Database.Relational.Derives+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines typed SQLs derived from type informations.+module Database.Relational.Derives (+ -- * Query derivation+ specifiedKey,++ unique,++ primary', primary,++ -- * Update derivation+ updateByConstraintKey,+ primaryUpdate,++ updateValuesWithKey,++ -- * Derived objects from table+ derivedUniqueRelation+ ) where++import Database.Record (PersistableWidth, ToSql)+import Database.Record.ToSql (unsafeUpdateValuesWithIndexes)++import Database.Relational.SqlSyntax (Record)++import Database.Relational.Table (Table, TableDerivable)+import Database.Relational.Pi.Unsafe (Pi, unsafeExpandIndexes)+import qualified Database.Relational.Record as Record+import Database.Relational.Projectable (placeholder, (.=.))+import Database.Relational.ProjectableExtended ((!))+import Database.Relational.Monad.Class (wheres)+import Database.Relational.Monad.BaseType (Relation, relationWidth)+import Database.Relational.Relation+ (derivedRelation, relation, relation', query, UniqueRelation, unsafeUnique)+import Database.Relational.Constraint+ (Key, Primary, Unique, projectionKey, uniqueKey,+ HasConstraintKey(constraintKey))+import qualified Database.Relational.Constraint as Constraint+import Database.Relational.Type (KeyUpdate, typedKeyUpdate)+++-- | Query restricted with specified key.+specifiedKey :: PersistableWidth p+ => Pi a p -- ^ Unique key proof object which record type is 'a' and key type is 'p'.+ -> Relation () a -- ^ 'Relation' to add restriction.+ -> Relation p a -- ^ Result restricted 'Relation'+specifiedKey key rel = relation' $ do+ q <- query rel+ (param, ()) <- placeholder (\ph -> wheres $ Record.wpi (relationWidth rel) q key .=. ph)+ return (param, q)++-- | Query restricted with specified unique key.+unique :: PersistableWidth p+ => Key Unique a p -- ^ Unique key proof object which record type is 'a' and key type is 'p'.+ -> Relation () a -- ^ 'Relation' to add restriction.+ -> Relation p a -- ^ Result restricted 'Relation'+unique = specifiedKey . projectionKey++-- | Query restricted with specified primary key.+primary' :: PersistableWidth p+ => Key Primary a p -- ^ Primary key proof object which record type is 'a' and key type is 'p'.+ -> Relation () a -- ^ 'Relation' to add restriction.+ -> Relation p a -- ^ Result restricted 'Relation'+primary' = specifiedKey . projectionKey++-- | Query restricted with inferred primary key.+primary :: HasConstraintKey Primary a p+ => Relation () a -- ^ 'Relation' to add restriction.+ -> Relation p a -- ^ Result restricted 'Relation'+primary = primary' constraintKey+++-- | Convert from Haskell type `r` into SQL value `q` list expected by update form like+--+-- /UPDATE <table> SET c0 = ?, c1 = ?, ..., cn = ? WHERE key0 = ? AND key1 = ? AND key2 = ? ... /+--+-- using derived 'RecordToSql' proof object.+updateValuesWithKey :: ToSql q r+ => Pi r p+ -> r+ -> [q]+updateValuesWithKey = unsafeUpdateValuesWithIndexes . unsafeExpandIndexes++-- | Typed 'KeyUpdate' using specified constraint key.+updateByConstraintKey :: Table r -- ^ 'Table' to update+ -> Key c r p -- ^ Key with constraint 'c', record type 'r' and columns type 'p'+ -> KeyUpdate p r -- ^ Result typed 'Update'+updateByConstraintKey table' = typedKeyUpdate table' . Constraint.projectionKey++-- | Typed 'KeyUpdate' using inferred primary key.+primaryUpdate :: (HasConstraintKey Primary r p)+ => Table r -- ^ 'Table' to update+ -> KeyUpdate p r -- ^ Result typed 'Update'+primaryUpdate table' = updateByConstraintKey table' (uniqueKey constraintKey)++-- | 'UniqueRelation' inferred from table.+derivedUniqueRelation :: TableDerivable r+ => Key Unique r k -- ^ Unique key proof object which record type is 'a' and key type is 'p'.+ -> Record c k -- ^ Unique key value to specify.+ -> UniqueRelation () c r -- ^ Result restricted 'Relation'+derivedUniqueRelation uk kp = unsafeUnique . relation $ do+ r <- query derivedRelation+ wheres $ r ! projectionKey uk .=. Record.unsafeChangeContext kp+ return r
+ src/Database/Relational/Effect.hs view
@@ -0,0 +1,185 @@+-- |+-- Module : Database.Relational.Effect+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines effect statements+-- like update and delete.+module Database.Relational.Effect (+ -- * Object to express simple restriction.+ Restriction, restriction, restriction',++ -- * Object to express update target columns and restriction.+ UpdateTarget, updateTarget, updateTarget',+ liftTargetAllColumn, liftTargetAllColumn',+ updateTargetAllColumn, updateTargetAllColumn',++ -- * Object to express insert terget.+ InsertTarget, insertTarget, insertTarget', piRegister,++ -- * Generate SQL from restriction.+ sqlWhereFromRestriction,+ sqlFromUpdateTarget,+ sqlChunkFromInsertTarget,+ sqlFromInsertTarget,+ ) where++import Data.Monoid ((<>))+import Data.Functor.ProductIsomorphic (peRight)++import Language.SQL.Keyword (Keyword(..))+import Database.Record.Persistable (PersistableWidth)++import Database.Relational.Internal.Config (Config (chunksInsertSize), defaultConfig)+import Database.Relational.Internal.String (StringSQL, stringSQL, showStringSQL)+import Database.Relational.SqlSyntax+ (composeWhere, composeSets, composeChunkValuesWithColumns)++import Database.Relational.Pi (Pi, id')+import qualified Database.Relational.Pi.Unsafe as Pi+import Database.Relational.Table (Table, TableDerivable, derivedTable)+import qualified Database.Relational.Table as Table+import qualified Database.Relational.Record as Record+import Database.Relational.Projectable+ (PlaceHolders, unitPlaceHolder,+ pwPlaceholder, placeholder, (><), )+import Database.Relational.Monad.Trans.Assigning (assignings, (<-#))+import Database.Relational.Monad.Restrict (RestrictedStatement)+import qualified Database.Relational.Monad.Restrict as Restrict+import Database.Relational.Monad.Assign (AssignStatement)+import qualified Database.Relational.Monad.Assign as Assign+import Database.Relational.Monad.Register (Register)+import qualified Database.Relational.Monad.Register as Register+++-- | Restriction type with place-holder parameter 'p' and projected record type 'r'.+newtype Restriction p r = Restriction (RestrictedStatement r (PlaceHolders p))++-- | Finalize 'Restrict' monad and generate 'Restriction'.+restriction :: RestrictedStatement r () -> Restriction () r+restriction = Restriction . ((>> return unitPlaceHolder) .)++-- | Finalize 'Restrict' monad and generate 'Restriction' with place-holder parameter 'p'+restriction' :: RestrictedStatement r (PlaceHolders p) -> Restriction p r+restriction' = Restriction++runRestriction :: Restriction p r+ -> RestrictedStatement r (PlaceHolders p)+runRestriction (Restriction qf) = qf++-- | SQL WHERE clause 'StringSQL' string from 'Restriction'.+sqlWhereFromRestriction :: Config -> Table r -> Restriction p r -> StringSQL+sqlWhereFromRestriction config tbl (Restriction q) = composeWhere rs+ where (_ph, rs) = Restrict.extract (q $ Record.unsafeFromTable tbl) config++-- | Show where clause.+instance TableDerivable r => Show (Restriction p r) where+ show = showStringSQL . sqlWhereFromRestriction defaultConfig derivedTable+++-- | UpdateTarget type with place-holder parameter 'p' and projected record type 'r'.+newtype UpdateTarget p r = UpdateTarget (AssignStatement r (PlaceHolders p))++-- | Finalize 'Target' monad and generate 'UpdateTarget'.+updateTarget :: AssignStatement r ()+ -> UpdateTarget () r+updateTarget = UpdateTarget . ((>> return unitPlaceHolder) .)++-- | Finalize 'Target' monad and generate 'UpdateTarget' with place-holder parameter 'p'.+updateTarget' :: AssignStatement r (PlaceHolders p)+ -> UpdateTarget p r+updateTarget' = UpdateTarget++updateAllColumn :: PersistableWidth r+ => Restriction p r+ -> AssignStatement r (PlaceHolders (r, p))+updateAllColumn rs proj = do+ (ph0, ()) <- placeholder (\ph -> id' <-# ph)+ ph1 <- assignings $ runRestriction rs proj+ return $ ph0 >< ph1++-- | Lift 'Restriction' to 'UpdateTarget'. Update target columns are all.+liftTargetAllColumn :: PersistableWidth r+ => Restriction () r+ -> UpdateTarget r r+liftTargetAllColumn rs = updateTarget' $ \proj -> fmap peRight $ updateAllColumn rs proj++-- | Lift 'Restriction' to 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.+liftTargetAllColumn' :: PersistableWidth r+ => Restriction p r+ -> UpdateTarget (r, p) r+liftTargetAllColumn' rs = updateTarget' $ updateAllColumn rs++-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all.+updateTargetAllColumn :: PersistableWidth r+ => RestrictedStatement r ()+ -> UpdateTarget r r+updateTargetAllColumn = liftTargetAllColumn . restriction++-- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.+updateTargetAllColumn' :: PersistableWidth r+ => RestrictedStatement r (PlaceHolders p)+ -> UpdateTarget (r, p) r+updateTargetAllColumn' = liftTargetAllColumn' . restriction'+++-- | SQL SET clause and WHERE clause 'StringSQL' string from 'UpdateTarget'+sqlFromUpdateTarget :: Config -> Table r -> UpdateTarget p r -> StringSQL+sqlFromUpdateTarget config tbl (UpdateTarget q) = composeSets (asR tbl) <> composeWhere rs+ where ((_ph, asR), rs) = Assign.extract (q (Record.unsafeFromTable tbl)) config++instance TableDerivable r => Show (UpdateTarget p r) where+ show = showStringSQL . sqlFromUpdateTarget defaultConfig derivedTable+++-- | InsertTarget type with place-holder parameter 'p' and projected record type 'r'.+newtype InsertTarget p r = InsertTarget (Register r (PlaceHolders p))++-- | Finalize 'Register' monad and generate 'InsertTarget'.+insertTarget :: Register r ()+ -> InsertTarget () r+insertTarget = InsertTarget . (>> return unitPlaceHolder)++-- | Finalize 'Target' monad and generate 'UpdateTarget' with place-holder parameter 'p'.+insertTarget' :: Register r (PlaceHolders p)+ -> InsertTarget p r+insertTarget' = InsertTarget++-- | parametalized 'Register' monad from 'Pi'+piRegister :: PersistableWidth r+ => Pi r r'+ -> Register r (PlaceHolders r')+piRegister pi' = do+ let (ph', ma) = pwPlaceholder (Pi.width' pi') (\ph -> pi' <-# ph)+ () <- ma+ return ph'++sqlChunkFromInsertTarget' :: Config+ -> Int+ -> Table r+ -> InsertTarget p r+ -> StringSQL+sqlChunkFromInsertTarget' config sz tbl (InsertTarget q) =+ INSERT <> INTO <> stringSQL (Table.name tbl) <> composeChunkValuesWithColumns sz (asR tbl)+ where+ (_ph, asR) = Register.extract q config++-- | Make 'StringSQL' string of SQL INSERT record chunk statement from 'InsertTarget'+sqlChunkFromInsertTarget :: Config+ -> Table r+ -> InsertTarget p r+ -> (StringSQL, Int)+sqlChunkFromInsertTarget config tbl it =+ (sqlChunkFromInsertTarget' config n tbl it, n)+ where+ th = chunksInsertSize config+ n = (th + w - 1) `quot` w+ w = Table.width tbl++-- | Make 'StringSQL' string of SQL INSERT statement from 'InsertTarget'+sqlFromInsertTarget :: Config -> Table r -> InsertTarget p r -> StringSQL+sqlFromInsertTarget config = sqlChunkFromInsertTarget' config 1
+ src/Database/Relational/Internal/Config.hs view
@@ -0,0 +1,74 @@+-- |+-- Module : Database.Relational.Internal.Config+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines configuration datatype used in query products.+module Database.Relational.Internal.Config (+ NameConfig (..),+ ProductUnitSupport (..), SchemaNameMode (..), IdentifierQuotation (..),+ Config ( productUnitSupport+ , chunksInsertSize+ , schemaNameMode+ , normalizedTableName+ , verboseAsCompilerWarning+ , identifierQuotation+ , nameConfig),+ defaultConfig,+ ) where++import Language.Haskell.TH.Name.CamelCase (VarName, varCamelcaseName)+import qualified Database.Record.TH as RecordTH+++-- | 'NameConfig' type to customize names of expanded templates.+data NameConfig =+ NameConfig+ { recordConfig :: RecordTH.NameConfig+ , relationVarName :: String -> String -> VarName+ }++instance Show NameConfig where+ show = const "<NameConfig>"++-- | Unit of product is supported or not.+data ProductUnitSupport = PUSupported | PUNotSupported deriving Show++-- | Schema name qualify mode in SQL string.+data SchemaNameMode+ = SchemaQualified -- ^ Schema qualified table name in SQL string+ | SchemaNotQualified -- ^ Not qualified table name in SQL string+ deriving (Eq, Show)++-- | Configuration for quotation of identifiers of SQL.+data IdentifierQuotation = NoQuotation | Quotation Char deriving Show++-- | Configuration type.+data Config =+ Config+ { productUnitSupport :: !ProductUnitSupport+ , chunksInsertSize :: !Int+ , schemaNameMode :: !SchemaNameMode+ , normalizedTableName :: !Bool+ , verboseAsCompilerWarning :: !Bool+ , identifierQuotation :: !IdentifierQuotation+ , nameConfig :: !NameConfig+ } deriving Show++-- | Default configuration.+defaultConfig :: Config+defaultConfig =+ Config { productUnitSupport = PUSupported+ , chunksInsertSize = 256+ , schemaNameMode = SchemaQualified+ , normalizedTableName = True+ , verboseAsCompilerWarning = False+ , identifierQuotation = NoQuotation+ , nameConfig = NameConfig { recordConfig = RecordTH.defaultNameConfig+ , relationVarName = const varCamelcaseName+ }+ }
+ src/Database/Relational/Internal/ContextType.hs view
@@ -0,0 +1,39 @@+{-# LANGUAGE EmptyDataDecls #-}++-- |+-- Module : Database.Relational.Internal.ContextType+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines query context tag types.+module Database.Relational.Internal.ContextType (+ Flat, Aggregated, Exists, OverWindow,++ Set, SetList, Power,+ ) where++-- | Type tag for flat (not-aggregated) query+data Flat++-- | Type tag for aggregated query+data Aggregated++-- | Type tag for exists predicate+data Exists++-- | Type tag for window function building+data OverWindow+++-- | Type tag for normal aggregatings set+data Set++-- | Type tag for aggregatings GROUPING SETS+data SetList++-- | Type tag for aggregatings power set+data Power
+ src/Database/Relational/Internal/String.hs view
@@ -0,0 +1,62 @@+{-# LANGUAGE FlexibleInstances #-}++-- |+-- Module : Database.Relational.Internal.String+-- Copyright : 2014-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides SQL string wrap interfaces.+module Database.Relational.Internal.String (+ StringSQL, stringSQL, showStringSQL,++ rowStringSQL, rowPlaceHolderStringSQL,++ rowConsStringSQL, listStringSQL,++ boolSQL,+ ) where++import Language.SQL.Keyword (Keyword, word, wordShow, fold, (|*|), paren)+++-- | String wrap type for SQL strings.+type StringSQL = Keyword++-- | 'StringSQL' from 'String'.+stringSQL :: String -> StringSQL+stringSQL = word++-- | 'StringSQL' to 'String'.+showStringSQL :: StringSQL -> String+showStringSQL = wordShow++-- | Row String of SQL values.+rowStringSQL :: [StringSQL] -> StringSQL+rowStringSQL = d where+ d [] = error "Record: no columns. empty row is not allowed in SQL."+ d [c] = c+ d cs = paren $ fold (|*|) cs++-- | Place holder row String of SQL.+rowPlaceHolderStringSQL :: Int -> StringSQL+rowPlaceHolderStringSQL = rowStringSQL . (`replicate` stringSQL "?")++-- | List String of SQL.+rowConsStringSQL :: [StringSQL] -> StringSQL+rowConsStringSQL = paren . fold (|*|)++-- | List String of SQL.+listStringSQL :: [StringSQL] -> StringSQL+listStringSQL = paren . fold (|*|)++-- | SQL expressions for Bool type.+boolSQL :: Bool -> StringSQL+boolSQL =+ stringSQL . d+ where+ d True = "(0=0)"+ d False = "(0=1)"
+ src/Database/Relational/Internal/UntypedTable.hs view
@@ -0,0 +1,44 @@+-- |+-- Module : Database.Relational.Internal.UntypedTable+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines no-phantom table type which has table metadatas.+module Database.Relational.Internal.UntypedTable (+ Untyped (Untyped), name', width', columns', (!),+ ) where++import Data.Array (Array, elems)+import qualified Data.Array as Array++import Database.Relational.Internal.String (StringSQL)+++-- | Untyped typed table type+data Untyped = Untyped String Int (Array Int StringSQL) deriving Show++-- | Name string of table in SQL+name' :: Untyped -> String+name' (Untyped n _ _) = n++-- | Width of table+width' :: Untyped -> Int+width' (Untyped _ w _) = w++-- | Column name strings in SQL+columnArray :: Untyped -> Array Int StringSQL+columnArray (Untyped _ _ c) = c++-- | Column name strings in SQL+columns' :: Untyped -> [StringSQL]+columns' = elems . columnArray++-- | Column name string in SQL specified by index+(!) :: Untyped+ -> Int -- ^ Column index+ -> StringSQL -- ^ Column name String in SQL+t ! i = columnArray t Array.! i
+ src/Database/Relational/Monad/Aggregate.hs view
@@ -0,0 +1,103 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE TypeSynonymInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Aggregate+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about aggregated query type.+module Database.Relational.Monad.Aggregate (+ -- * Aggregated Query+ QueryAggregate,+ AggregatedQuery,++ toSQL,++ toSubQuery,++ Window, over+ ) where++import Data.Functor.Identity (Identity (runIdentity))+import Data.Monoid ((<>))++import Language.SQL.Keyword (Keyword(..))+import qualified Language.SQL.Keyword as SQL++import Database.Relational.Internal.ContextType (Flat, Aggregated, OverWindow)+import Database.Relational.SqlSyntax+ (Duplication, Record, SubQuery, Predicate, JoinProduct,+ OrderingTerm, composeOrderBy, aggregatedSubQuery,+ AggregateColumnRef, AggregateElem, composePartitionBy, )+import qualified Database.Relational.SqlSyntax as Syntax++import qualified Database.Relational.Record as Record+import Database.Relational.Projectable (PlaceHolders, SqlContext)+import Database.Relational.Monad.Class (MonadRestrict(..))+import Database.Relational.Monad.Trans.Restricting+ (Restrictings, restrictings, extractRestrict)+import Database.Relational.Monad.Trans.Aggregating+ (extractAggregateTerms, AggregatingSetT, PartitioningSet)+import Database.Relational.Monad.Trans.Ordering+ (Orderings, extractOrderingTerms)+import Database.Relational.Monad.BaseType (ConfigureQuery, askConfig)+import Database.Relational.Monad.Type (QueryCore, extractCore, OrderedQuery)+++-- | Aggregated query monad type.+type QueryAggregate = Orderings Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore))++-- | Aggregated query type. 'AggregatedQuery' p r == 'QueryAggregate' ('PlaceHolders' p, 'Record' 'Aggregated' r).+type AggregatedQuery p r = OrderedQuery Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore)) p r++-- | Partition monad type for partition-by clause.+type Window c = Orderings c (PartitioningSet c)++-- | Restricted 'MonadRestrict' instance.+instance MonadRestrict Flat q => MonadRestrict Flat (Restrictings Aggregated q) where+ restrict = restrictings . restrict++extract :: AggregatedQuery p r+ -> ConfigureQuery (((((((PlaceHolders p, Record Aggregated r), [OrderingTerm]),+ [Predicate Aggregated]),+ [AggregateElem]),+ [Predicate Flat]),+ JoinProduct), Duplication)+extract = extractCore . extractAggregateTerms . extractRestrict . extractOrderingTerms++-- | Run 'AggregatedQuery' to get SQL with 'ConfigureQuery' computation.+toSQL :: AggregatedQuery p r -- ^ 'AggregatedQuery' to run+ -> ConfigureQuery String -- ^ Result SQL string with 'ConfigureQuery' computation+toSQL = fmap Syntax.toSQL . toSubQuery++-- | Run 'AggregatedQuery' to get 'SubQuery' with 'ConfigureQuery' computation.+toSubQuery :: AggregatedQuery p r -- ^ 'AggregatedQuery' to run+ -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'ConfigureQuery' computation+toSubQuery q = do+ (((((((_ph, pj), ot), grs), ag), rs), pd), da) <- extract q+ c <- askConfig+ return $ aggregatedSubQuery c (Record.untype pj) da pd rs ag grs ot++extractWindow :: Window c a -> ((a, [OrderingTerm]), [AggregateColumnRef])+extractWindow = runIdentity . extractAggregateTerms . extractOrderingTerms++-- | Operator to make record of window function result using built 'Window' monad.+over :: SqlContext c+ => Record OverWindow a+ -> Window c ()+ -> Record c a+wp `over` win =+ Record.unsafeFromSqlTerms+ [ c <> OVER <> SQL.paren (composePartitionBy pt <> composeOrderBy ot)+ | c <- Record.columns wp+ ] where (((), ot), pt) = extractWindow win++infix 8 `over`
+ src/Database/Relational/Monad/Assign.hs view
@@ -0,0 +1,48 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Assign+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about restrict context with assignment monad type.+module Database.Relational.Monad.Assign (+ -- * Monad to restrict target records with assignment.+ Assign, AssignStatement,+ -- updateStatement,+ extract,+ ) where++import Database.Relational.Internal.Config (Config)+import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Predicate, Record, Assignment)++import Database.Relational.Table (Table)+import Database.Relational.Monad.Restrict (Restrict)+import qualified Database.Relational.Monad.Restrict as Restrict+import Database.Relational.Monad.Trans.Assigning (Assignings, extractAssignments)+++-- | Target update monad type used from update statement and merge statement.+type Assign r = Assignings r Restrict++-- | AssignStatement type synonym.+-- Specifying assignments and restrictions like update statement.+-- Record type must be+-- the same as 'Target' type parameter 'r'.+type AssignStatement r a = Record Flat r -> Assign r a++-- -- | 'return' of 'Update'+-- updateStatement :: a -> Assignings r (Restrictings Identity) a+-- updateStatement = assignings . restrictings . Identity++-- | Run 'Assign'.+extract :: Assign r a -> Config -> ((a, Table r -> [Assignment]), [Predicate Flat])+extract = Restrict.extract . extractAssignments
+ src/Database/Relational/Monad/BaseType.hs view
@@ -0,0 +1,95 @@+-- |+-- Module : Database.Relational.Monad.BaseType+-- Copyright : 2015-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines base monad type to build queries.+module Database.Relational.Monad.BaseType+ ( -- * Base monad type to build queries+ ConfigureQuery, configureQuery,+ qualifyQuery, askConfig,++ -- * Relation type+ Relation, unsafeTypeRelation, untypeRelation, relationWidth,++ dump,+ sqlFromRelationWith, sqlFromRelation,++ rightPh, leftPh,+ ) where++import Data.Functor.Identity (Identity, runIdentity)+import Control.Applicative ((<$>))++import Database.Record.Persistable (PersistableRecordWidth, unsafePersistableRecordWidth)++import Database.Relational.Internal.String (StringSQL, showStringSQL)+import Database.Relational.Internal.Config (Config, defaultConfig)+import Database.Relational.SqlSyntax (Qualified, SubQuery, showSQL, width)++import qualified Database.Relational.Monad.Trans.Qualify as Qualify+import Database.Relational.Monad.Trans.Qualify (Qualify, qualify, evalQualifyPrime)+import Database.Relational.Monad.Trans.Config (QueryConfig, runQueryConfig, askQueryConfig)++-- | Thin monad type for untyped structure.+type ConfigureQuery = Qualify (QueryConfig Identity)++-- | Run 'ConfigureQuery' monad with initial state to get only result.+configureQuery :: ConfigureQuery q -> Config -> q+configureQuery cq c = runIdentity $ runQueryConfig (evalQualifyPrime cq) c++-- | Get qualifyed table form query.+qualifyQuery :: a -> ConfigureQuery (Qualified a)+qualifyQuery = Qualify.qualifyQuery++-- | Read configuration.+askConfig :: ConfigureQuery Config+askConfig = qualify askQueryConfig+++-- | Relation type with place-holder parameter 'p' and query result type 'r'.+newtype Relation p r = SubQuery (ConfigureQuery SubQuery)++-- | Unsafely type qualified subquery into record typed relation type.+unsafeTypeRelation :: ConfigureQuery SubQuery -> Relation p r+unsafeTypeRelation = SubQuery++-- | Sub-query Qualify monad from relation.+untypeRelation :: Relation p r -> ConfigureQuery SubQuery+untypeRelation (SubQuery qsub) = qsub++-- | 'PersistableRecordWidth' of 'Relation' type.+relationWidth :: Relation p r -> PersistableRecordWidth r+relationWidth rel =+ unsafePersistableRecordWidth . width $ configureQuery (untypeRelation rel) defaultConfig+ --- Assume that width is independent from Config structure++unsafeCastPlaceHolder :: Relation a r -> Relation b r+unsafeCastPlaceHolder (SubQuery qsub) = SubQuery qsub++-- | Simplify placeholder type applying left identity element.+rightPh :: Relation ((), p) r -> Relation p r+rightPh = unsafeCastPlaceHolder++-- | Simplify placeholder type applying right identity element.+leftPh :: Relation (p, ()) r -> Relation p r+leftPh = unsafeCastPlaceHolder++-- | Generate SQL string from 'Relation' with configuration.+sqlFromRelationWith :: Relation p r -> Config -> StringSQL+sqlFromRelationWith = configureQuery . (showSQL <$>) . untypeRelation++-- | SQL string from 'Relation'.+sqlFromRelation :: Relation p r -> StringSQL+sqlFromRelation = (`sqlFromRelationWith` defaultConfig)++-- | Dump internal structure tree.+dump :: Relation p r -> String+dump = show . (`configureQuery` defaultConfig) . untypeRelation++instance Show (Relation p r) where+ show = showStringSQL . sqlFromRelation
+ src/Database/Relational/Monad/Class.hs view
@@ -0,0 +1,94 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Class+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines query building interface classes.+module Database.Relational.Monad.Class+ ( -- * Query interface classes+ MonadQualify (..), MonadRestrict (..),+ MonadQuery (..), MonadAggregate (..), MonadPartition (..),++ all', distinct,+ on, wheres, having,+ ) where++import Database.Relational.Internal.ContextType (Flat, Aggregated)+import Database.Relational.SqlSyntax+ (Duplication (..), Predicate, Record, AggregateKey)++import Database.Relational.Projectable (PlaceHolders)+import Database.Relational.Monad.BaseType (ConfigureQuery, Relation)+++-- | Restrict context interface+class (Functor m, Monad m) => MonadRestrict c m where+ -- | Add restriction to this context.+ restrict :: Predicate c -- ^ 'Record' which represent restriction+ -> m () -- ^ Restricted query context++-- | Query building interface.+class (Functor m, Monad m, MonadQualify ConfigureQuery m) => MonadQuery m where+ -- | Specify duplication.+ setDuplication :: Duplication -> m ()+ -- | Add restriction to last join.+ restrictJoin :: Predicate Flat -- ^ 'Record' which represent restriction+ -> m () -- ^ Restricted query context+ {- Haddock BUG? -}+ -- | Join sub-query with place-holder parameter 'p'. query result is not 'Maybe'.+ query' :: Relation p r+ -> m (PlaceHolders p, Record Flat r)+ -- | Join sub-query with place-holder parameter 'p'. Query result is 'Maybe'.+ queryMaybe' :: Relation p r+ -> m (PlaceHolders p, Record Flat (Maybe r))++-- | Lift interface from base qualify monad.+class (Functor q, Monad q, Functor m, Monad m) => MonadQualify q m where+ -- | Lift from qualify monad 'q' into 'MonadQuery' m.+ -- Qualify monad qualifies table form 'SubQuery'.+ liftQualify :: q a -> m a++instance (Functor q, Monad q) => MonadQualify q q where+ liftQualify = id++-- | Aggregated query building interface extends 'MonadQuery'.+class MonadQuery m => MonadAggregate m where+ -- | Add /GROUP BY/ term into context and get aggregated record.+ groupBy :: Record Flat r -- ^ Record to add into group by+ -> m (Record Aggregated r) -- ^ Result context and aggregated record+ -- | Add /GROUP BY/ term into context and get aggregated record. Non-traditional group-by version.+ groupBy' :: AggregateKey (Record Aggregated r) -- ^ Key to aggretate for non-traditional group-by interface+ -> m (Record Aggregated r) -- ^ Result context and aggregated record++-- | Window specification building interface.+class Monad m => MonadPartition c m where+ -- | Add /PARTITION BY/ term into context.+ partitionBy :: Record c r -> m ()++-- | Specify ALL attribute to query context.+all' :: MonadQuery m => m ()+all' = setDuplication All++-- | Specify DISTINCT attribute to query context.+distinct :: MonadQuery m => m ()+distinct = setDuplication Distinct++-- | Add restriction to last join. Record type version.+on :: MonadQuery m => Predicate Flat -> m ()+on = restrictJoin++-- | Add restriction to this not aggregated query.+wheres :: MonadRestrict Flat m => Predicate Flat -> m ()+wheres = restrict++-- | Add restriction to this aggregated query. Aggregated Record type version.+having :: MonadRestrict Aggregated m => Predicate Aggregated -> m ()+having = restrict
+ src/Database/Relational/Monad/Register.hs view
@@ -0,0 +1,31 @@+-- |+-- Module : Database.Relational.Monad.Register+-- Copyright : 2015-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about assignment monad type to build insert statement.+module Database.Relational.Monad.Register (+ -- * Monad to register target records.+ Register,++ extract,+ ) where++import Database.Relational.Internal.Config (Config)+import Database.Relational.SqlSyntax (Assignment)++import Database.Relational.Table (Table)+import Database.Relational.Monad.BaseType (ConfigureQuery, configureQuery)+import Database.Relational.Monad.Trans.Assigning (Assignings, extractAssignments)+++-- | Target register monad type used from insert statement.+type Register r = Assignings r ConfigureQuery++-- | Run 'InsertStatement'.+extract :: Assignings r ConfigureQuery a -> Config -> (a, Table r -> [Assignment])+extract = configureQuery . extractAssignments
+ src/Database/Relational/Monad/Restrict.hs view
@@ -0,0 +1,46 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Restrict+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about simple restrict context monad type.+module Database.Relational.Monad.Restrict (+ -- * Monad to restrict target records.+ Restrict, RestrictedStatement,++ -- restricted,+ extract+ ) where++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.Internal.Config (Config)+import Database.Relational.SqlSyntax (Predicate, Record)++import Database.Relational.Monad.Trans.Restricting+ (Restrictings, extractRestrict)+import Database.Relational.Monad.BaseType (ConfigureQuery, configureQuery)+++-- | Restrict only monad type used from update statement and delete statement.+type Restrict = Restrictings Flat ConfigureQuery++-- | RestrictedStatement type synonym.+-- Record type 'r' must be+-- the same as 'Restrictings' type parameter 'r'.+type RestrictedStatement r a = Record Flat r -> Restrict a++-- -- | 'return' of 'Restrict'+-- restricted :: a -> Restrict a+-- restricted = restrict . Identity++-- | Run 'Restrict' to get 'QueryRestriction'.+extract :: Restrict a -> Config -> (a, [Predicate Flat])+extract = configureQuery . extractRestrict
+ src/Database/Relational/Monad/Simple.hs view
@@ -0,0 +1,67 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Simple+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about simple (not-aggregated) query type.+module Database.Relational.Monad.Simple (+ -- * Simple query+ QuerySimple, SimpleQuery,++ simple,++ toSQL,+ toSubQuery,+ ) where++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Duplication, OrderingTerm, JoinProduct, Predicate, Record,+ SubQuery, flatSubQuery, )+import qualified Database.Relational.SqlSyntax as Syntax++import qualified Database.Relational.Record as Record+import Database.Relational.Monad.Trans.Join (join')+import Database.Relational.Monad.Trans.Restricting (restrictings)+import Database.Relational.Monad.Trans.Ordering+ (Orderings, orderings, extractOrderingTerms)+import Database.Relational.Monad.BaseType (ConfigureQuery, askConfig)+import Database.Relational.Monad.Type (QueryCore, extractCore, OrderedQuery)+import Database.Relational.Projectable (PlaceHolders)+++-- | Simple (not-aggregated) query monad type.+type QuerySimple = Orderings Flat QueryCore++-- | Simple (not-aggregated) query type. 'SimpleQuery'' p r == 'QuerySimple' ('PlaceHolders' p, 'Record' r).+type SimpleQuery p r = OrderedQuery Flat QueryCore p r++-- | Lift from qualified table forms into 'QuerySimple'.+simple :: ConfigureQuery a -> QuerySimple a+simple = orderings . restrictings . join'++extract :: SimpleQuery p r+ -> ConfigureQuery (((((PlaceHolders p, Record Flat r), [OrderingTerm]), [Predicate Flat]),+ JoinProduct), Duplication)+extract = extractCore . extractOrderingTerms++-- | Run 'SimpleQuery' to get SQL string with 'Qualify' computation.+toSQL :: SimpleQuery p r -- ^ 'SimpleQuery' to run+ -> ConfigureQuery String -- ^ Result SQL string with 'Qualify' computation+toSQL = fmap Syntax.toSQL . toSubQuery++-- | Run 'SimpleQuery' to get 'SubQuery' with 'Qualify' computation.+toSubQuery :: SimpleQuery p r -- ^ 'SimpleQuery'' to run+ -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'Qualify' computation+toSubQuery q = do+ (((((_ph, pj), ot), rs), pd), da) <- extract q+ c <- askConfig+ return $ flatSubQuery c (Record.untype pj) da pd rs ot
+ src/Database/Relational/Monad/Trans/Aggregating.hs view
@@ -0,0 +1,170 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Trans.Aggregating+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which lift+-- from 'MonadQuery' into Aggregated query.+module Database.Relational.Monad.Trans.Aggregating+ ( -- * Transformer into aggregated query+ Aggregatings, aggregatings,++ AggregatingSetT, AggregatingSetListT, AggregatingPowerSetT, PartitioningSetT,++ -- * Result+ extractAggregateTerms,++ -- * Grouping sets support+ AggregatingSet, AggregatingPowerSet, AggregatingSetList, PartitioningSet,+ key, key', set,+ bkey, rollup, cube, groupingSets,+ ) where++import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Control.Applicative (Applicative, pure, (<$>))+import Control.Arrow (second)+import Data.DList (DList, toList)++import Data.Functor.Identity (Identity (runIdentity))++import Database.Relational.Internal.ContextType+ (Flat, Aggregated, Set, Power, SetList)+import Database.Relational.SqlSyntax+ (Record,+ AggregateColumnRef, AggregateElem, aggregateColumnRef, AggregateSet, aggregateGroupingSet,+ AggregateBitKey, aggregatePowerKey, aggregateRollup, aggregateCube, aggregateSets,+ AggregateKey, aggregateKeyRecord, aggregateKeyElement, unsafeAggregateKey)++import qualified Database.Relational.Record as Record+import Database.Relational.Monad.Class+ (MonadQualify (..), MonadRestrict(..), MonadQuery(..), MonadAggregate(..), MonadPartition(..))+++-- | Type to accumulate aggregating context.+-- Type 'ac' is aggregating-context type like aggregating key set building,+-- aggregating key sets set building and partition key set building.+-- Type 'at' is aggregating term type.+newtype Aggregatings ac at m a =+ Aggregatings (WriterT (DList at) m a)+ deriving (MonadTrans, Monad, Functor, Applicative)++-- | Lift to 'Aggregatings'.+aggregatings :: Monad m => m a -> Aggregatings ac at m a+aggregatings = lift++-- | Context type building one grouping set.+type AggregatingSetT = Aggregatings Set AggregateElem++-- | Context type building grouping sets list.+type AggregatingSetListT = Aggregatings SetList AggregateSet++-- | Context type building power group set.+type AggregatingPowerSetT = Aggregatings Power AggregateBitKey++-- | Context type building partition keys set.+type PartitioningSetT c = Aggregatings c AggregateColumnRef++-- | Aggregated 'MonadRestrict'.+instance MonadRestrict c m => MonadRestrict c (AggregatingSetT m) where+ restrict = aggregatings . restrict++-- | Aggregated 'MonadQualify'.+instance MonadQualify q m => MonadQualify q (AggregatingSetT m) where+ liftQualify = aggregatings . liftQualify++-- | Aggregated 'MonadQuery'.+instance MonadQuery m => MonadQuery (AggregatingSetT m) where+ setDuplication = aggregatings . setDuplication+ restrictJoin = aggregatings . restrictJoin+ query' = aggregatings . query'+ queryMaybe' = aggregatings . queryMaybe'++unsafeAggregateWithTerm :: Monad m => at -> Aggregatings ac at m ()+unsafeAggregateWithTerm = Aggregatings . tell . pure++aggregateKey :: Monad m => AggregateKey a -> Aggregatings ac AggregateElem m a+aggregateKey k = do+ unsafeAggregateWithTerm $ aggregateKeyElement k+ return $ aggregateKeyRecord k++-- | Aggregated query instance.+instance MonadQuery m => MonadAggregate (AggregatingSetT m) where+ groupBy p = do+ mapM_ unsafeAggregateWithTerm [ aggregateColumnRef col | col <- Record.columns p]+ return $ Record.unsafeToAggregated p+ groupBy' = aggregateKey++-- | Partition clause instance+instance Monad m => MonadPartition c (PartitioningSetT c m) where+ partitionBy = mapM_ unsafeAggregateWithTerm . Record.columns++-- | Run 'Aggregatings' to get terms list.+extractAggregateTerms :: (Monad m, Functor m) => Aggregatings ac at m a -> m (a, [at])+extractAggregateTerms (Aggregatings ac) = second toList <$> runWriterT ac++extractTermList :: Aggregatings ac at Identity a -> (a, [at])+extractTermList = runIdentity . extractAggregateTerms++-- | Context monad type to build single grouping set.+type AggregatingSet = AggregatingSetT Identity++-- | Context monad type to build grouping power set.+type AggregatingPowerSet = AggregatingPowerSetT Identity++-- | Context monad type to build grouping set list.+type AggregatingSetList = AggregatingSetListT Identity++-- | Context monad type to build partition keys set.+type PartitioningSet c = PartitioningSetT c Identity++-- | Specify key of single grouping set from Record.+key :: Record Flat r+ -> AggregatingSet (Record Aggregated (Maybe r))+key p = do+ mapM_ unsafeAggregateWithTerm [ aggregateColumnRef col | col <- Record.columns p]+ return . Record.just $ Record.unsafeToAggregated p++-- | Specify key of single grouping set.+key' :: AggregateKey a+ -> AggregatingSet a+key' = aggregateKey++-- | Finalize and specify single grouping set.+set :: AggregatingSet a+ -> AggregatingSetList a+set s = do+ let (p, c) = second aggregateGroupingSet . extractTermList $ s+ unsafeAggregateWithTerm c+ return p++-- | Specify key of rollup and cube power set.+bkey :: Record Flat r+ -> AggregatingPowerSet (Record Aggregated (Maybe r))+bkey p = do+ unsafeAggregateWithTerm . aggregatePowerKey $ Record.columns p+ return . Record.just $ Record.unsafeToAggregated p++finalizePower :: ([AggregateBitKey] -> AggregateElem)+ -> AggregatingPowerSet a -> AggregateKey a+finalizePower finalize pow = unsafeAggregateKey . second finalize . extractTermList $ pow++-- | Finalize grouping power set as rollup power set.+rollup :: AggregatingPowerSet a -> AggregateKey a+rollup = finalizePower aggregateRollup++-- | Finalize grouping power set as cube power set.+cube :: AggregatingPowerSet a -> AggregateKey a+cube = finalizePower aggregateCube++-- | Finalize grouping set list.+groupingSets :: AggregatingSetList a -> AggregateKey a+groupingSets = unsafeAggregateKey . second aggregateSets . extractTermList
+ src/Database/Relational/Monad/Trans/Assigning.hs view
@@ -0,0 +1,84 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Trans.Assigning+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which lift+-- from context into context with assigning.+module Database.Relational.Monad.Trans.Assigning (+ -- * Transformer into context with assignments+ Assignings, assignings,++ -- * API of context with assignments+ assignTo, (<-#), AssignTarget,++ -- * Result SQL set clause+ extractAssignments+ ) where++import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Control.Applicative (Applicative, pure, (<$>))+import Control.Arrow (second)+import Data.Monoid (mconcat)+import Data.DList (DList, toList)++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax (Record, Assignment)++import Database.Relational.Pi (Pi)+import Database.Relational.Table (Table, recordWidth)+import qualified Database.Relational.Record as Record+import Database.Relational.Monad.Class (MonadQualify (..), MonadRestrict(..))+++-- | Type to accumulate assigning context.+-- Type 'r' is table record type.+newtype Assignings r m a =+ Assignings (WriterT (Table r -> DList Assignment) m a)+ deriving (MonadTrans, Monad, Functor, Applicative)++-- | Lift to 'Assignings'+assignings :: Monad m => m a -> Assignings r m a+assignings = lift++-- | 'MonadRestrict' with assigning.+instance MonadRestrict c m => MonadRestrict c (Assignings r m) where+ restrict = assignings . restrict++-- | 'MonadQualify' with assigning.+instance MonadQualify q m => MonadQualify q (Assignings r m) where+ liftQualify = assignings . liftQualify++-- | Target of assignment.+type AssignTarget r v = Pi r v++targetRecord :: AssignTarget r v -> Table r -> Record Flat v+targetRecord pi' tbl = Record.wpi (recordWidth tbl) (Record.unsafeFromTable tbl) pi'++-- | Add an assignment.+assignTo :: Monad m => Record Flat v -> AssignTarget r v -> Assignings r m ()+assignTo vp target = Assignings . tell+ $ \t -> mconcat $ zipWith (curry pure) (leftsR t) rights where+ leftsR = Record.columns . targetRecord target+ rights = Record.columns vp++-- | Add and assginment.+(<-#) :: Monad m => AssignTarget r v -> Record Flat v -> Assignings r m ()+(<-#) = flip assignTo++infix 4 <-#++-- | Run 'Assignings' to get 'Assignments'+extractAssignments :: (Monad m, Functor m)+ => Assignings r m a+ -> m (a, Table r -> [Assignment])+extractAssignments (Assignings ac) = second (toList .) <$> runWriterT ac
+ src/Database/Relational/Monad/Trans/Config.hs view
@@ -0,0 +1,41 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- |+-- Module : Database.Relational.Monad.Trans.Config+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which requires query generate configuration.+module Database.Relational.Monad.Trans.Config (+ -- * Transformer into query with configuration+ QueryConfig, queryConfig,+ runQueryConfig, askQueryConfig+ ) where++import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.Reader (ReaderT, runReaderT, ask)+import Control.Applicative (Applicative)++import Database.Relational.Internal.Config (Config)+++-- | 'ReaderT' type to require query generate configuration.+newtype QueryConfig m a =+ QueryConfig (ReaderT Config m a)+ deriving (Monad, Functor, Applicative)++-- | Run 'QueryConfig' to expand with configuration+runQueryConfig :: QueryConfig m a -> Config -> m a+runQueryConfig (QueryConfig r) = runReaderT r++-- | Lift to 'QueryConfig'.+queryConfig :: Monad m => m a -> QueryConfig m a+queryConfig = QueryConfig . lift++-- | Read configuration.+askQueryConfig :: Monad m => QueryConfig m Config+askQueryConfig = QueryConfig ask
+ src/Database/Relational/Monad/Trans/Join.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Trans.Join+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which lift to basic 'MonadQuery'.+module Database.Relational.Monad.Trans.Join+ ( -- * Transformer into join query+ QueryJoin, join',++ -- * Result+ extractProduct,++ -- * Unsafe API+ unsafeSubQueryWithAttr,+ ) where++import Prelude hiding (product)+import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Control.Monad.Trans.State (modify, StateT, runStateT)+import Control.Applicative (Applicative, (<$>))+import Control.Arrow (second, (***))+import Data.Maybe (fromMaybe)+import Data.Monoid (Last (Last, getLast))++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Duplication (All), NodeAttr (Just', Maybe), Predicate, Record,+ SubQuery, Qualified, JoinProduct, restrictProduct, growProduct, )++import Database.Relational.Monad.Trans.JoinState+ (JoinContext, primeJoinContext, updateProduct, joinProduct)+import qualified Database.Relational.Record as Record+import Database.Relational.Projectable (PlaceHolders, unsafeAddPlaceHolders)+import Database.Relational.Monad.BaseType (ConfigureQuery, qualifyQuery, Relation, untypeRelation)+import Database.Relational.Monad.Class (MonadQualify (..), MonadQuery (..))+++-- | 'StateT' type to accumulate join product context.+newtype QueryJoin m a =+ QueryJoin (StateT JoinContext (WriterT (Last Duplication) m) a)+ deriving (Monad, Functor, Applicative)++instance MonadTrans QueryJoin where+ lift = QueryJoin . lift . lift++-- | Lift to 'QueryJoin'+join' :: Monad m => m a -> QueryJoin m a+join' = lift++-- | Unsafely update join product context.+updateContext :: Monad m => (JoinContext -> JoinContext) -> QueryJoin m ()+updateContext = QueryJoin . modify++-- | Add last join product restriction.+updateJoinRestriction :: Monad m => Predicate Flat -> QueryJoin m ()+updateJoinRestriction e = updateContext (updateProduct d) where+ d Nothing = error "on: Product is empty! Restrict target product is not found!"+ d (Just pt) = restrictProduct pt e++instance MonadQualify q m => MonadQualify q (QueryJoin m) where+ liftQualify = join' . liftQualify++-- | Joinable query instance.+instance MonadQuery (QueryJoin ConfigureQuery) where+ setDuplication = QueryJoin . lift . tell . Last . Just+ restrictJoin = updateJoinRestriction+ query' = queryWithAttr Just'+ queryMaybe' pr = do+ (ph, pj) <- queryWithAttr Maybe pr+ return (ph, Record.just pj)++-- | Unsafely join sub-query with this query.+unsafeSubQueryWithAttr :: Monad q+ => NodeAttr -- ^ Attribute maybe or just+ -> Qualified SubQuery -- ^ 'SubQuery' to join+ -> QueryJoin q (Record c r) -- ^ Result joined context and record of 'SubQuery' result.+unsafeSubQueryWithAttr attr qsub = do+ updateContext (updateProduct (`growProduct` (attr, qsub)))+ return $ Record.unsafeFromQualifiedSubQuery qsub++-- | Basic monadic join operation using 'MonadQuery'.+queryWithAttr :: NodeAttr+ -> Relation p r+ -> QueryJoin ConfigureQuery (PlaceHolders p, Record c r)+queryWithAttr attr = unsafeAddPlaceHolders . run where+ run rel = do+ q <- liftQualify $ do+ sq <- untypeRelation rel+ qualifyQuery sq+ unsafeSubQueryWithAttr attr q++-- | Run 'QueryJoin' to get 'JoinProduct'+extractProduct :: Functor m => QueryJoin m a -> m ((a, JoinProduct), Duplication)+extractProduct (QueryJoin s) = (second joinProduct *** (fromMaybe All . getLast))+ <$> runWriterT (runStateT s primeJoinContext)
+ src/Database/Relational/Monad/Trans/JoinState.hs view
@@ -0,0 +1,45 @@+-- |+-- Module : Database.Relational.Monad.Trans.JoinState+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides state definition for+-- "Database.Relational.Monad.Trans.Join".+--+-- This is not public interface.+module Database.Relational.Monad.Trans.JoinState (+ -- * Join context+ JoinContext, primeJoinContext, updateProduct, joinProduct+ ) where++import Prelude hiding (product)+import Data.DList (DList, toList)++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax (JoinProduct, Node, Predicate)+import qualified Database.Relational.SqlSyntax as Product+++-- | JoinContext type for QueryJoin.+newtype JoinContext =+ JoinContext+ { product :: Maybe (Node (DList (Predicate Flat)))+ }++-- | Initial 'JoinContext'.+primeJoinContext :: JoinContext+primeJoinContext = JoinContext Nothing++-- | Update product of 'JoinContext'.+updateProduct :: (Maybe (Node (DList (Predicate Flat))) -> Node (DList (Predicate Flat)))+ -> JoinContext+ -> JoinContext+updateProduct uf ctx = ctx { product = Just . uf . product $ ctx }++-- | Finalize context to extract accumulated query product.+joinProduct :: JoinContext -> JoinProduct+joinProduct = fmap (fmap toList . Product.nodeTree) . product
+ src/Database/Relational/Monad/Trans/Ordering.hs view
@@ -0,0 +1,113 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Trans.Ordering+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which lift+-- from query into query with ordering.+module Database.Relational.Monad.Trans.Ordering (+ -- * Transformer into query with ordering+ Orderings, orderings,++ -- * API of query with ordering+ orderBy', orderBy, asc, desc,++ -- * Result+ extractOrderingTerms+ ) where++import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Control.Applicative (Applicative, pure, (<$>))+import Control.Arrow (second)+import Data.DList (DList, toList)++import Database.Relational.SqlSyntax+ (Order (..), Nulls (..), OrderingTerm, Record)++import qualified Database.Relational.Record as Record+import Database.Relational.Monad.Class+ (MonadQualify (..), MonadRestrict(..), MonadQuery(..), MonadAggregate(..), MonadPartition(..))+++-- | Type to accumulate ordering context.+-- Type 'c' is ordering term record context type.+newtype Orderings c m a =+ Orderings (WriterT (DList OrderingTerm) m a)+ deriving (MonadTrans, Monad, Functor, Applicative)++-- | Lift to 'Orderings'.+orderings :: Monad m => m a -> Orderings c m a+orderings = lift++-- | 'MonadRestrict' with ordering.+instance MonadRestrict rc m => MonadRestrict rc (Orderings c m) where+ restrict = orderings . restrict++-- | 'MonadQualify' with ordering.+instance MonadQualify q m => MonadQualify q (Orderings c m) where+ liftQualify = orderings . liftQualify++-- | 'MonadQuery' with ordering.+instance MonadQuery m => MonadQuery (Orderings c m) where+ setDuplication = orderings . setDuplication+ restrictJoin = orderings . restrictJoin+ query' = orderings . query'+ queryMaybe' = orderings . queryMaybe'++-- | 'MonadAggregate' with ordering.+instance MonadAggregate m => MonadAggregate (Orderings c m) where+ groupBy = orderings . groupBy+ groupBy' = orderings . groupBy'++-- | 'MonadPartition' with ordering.+instance MonadPartition c m => MonadPartition c (Orderings c m) where+ partitionBy = orderings . partitionBy++-- | Add ordering terms.+updateOrderBys :: Monad m+ => (Order, Maybe Nulls) -- ^ Order direction+ -> Record c t -- ^ Ordering terms to add+ -> Orderings c m () -- ^ Result context with ordering+updateOrderBys opair p = Orderings . mapM_ tell $ terms where+ terms = curry pure opair `map` Record.columns p++-- | Add ordering terms with null ordering.+orderBy' :: Monad m+ => Record c t -- ^ Ordering terms to add+ -> Order -- ^ Order direction+ -> Nulls -- ^ Order of null+ -> Orderings c m () -- ^ Result context with ordering+orderBy' p o n = updateOrderBys (o, Just n) p++-- | Add ordering terms.+orderBy :: Monad m+ => Record c t -- ^ Ordering terms to add+ -> Order -- ^ Order direction+ -> Orderings c m () -- ^ Result context with ordering+orderBy p o = updateOrderBys (o, Nothing) p++-- | Add ascendant ordering term.+asc :: Monad m+ => Record c t -- ^ Ordering terms to add+ -> Orderings c m () -- ^ Result context with ordering+asc = updateOrderBys (Asc, Nothing)++-- | Add descendant ordering term.+desc :: Monad m+ => Record c t -- ^ Ordering terms to add+ -> Orderings c m () -- ^ Result context with ordering+desc = updateOrderBys (Desc, Nothing)++-- | Run 'Orderings' to get 'OrderingTerms'+extractOrderingTerms :: (Monad m, Functor m) => Orderings c m a -> m (a, [OrderingTerm])+extractOrderingTerms (Orderings oc) = second toList <$> runWriterT oc
+ src/Database/Relational/Monad/Trans/Qualify.hs view
@@ -0,0 +1,54 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- |+-- Module : Database.Relational.Monad.Trans.Qualify+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which qualify uniquely SQL table forms.+--+-- This is not public interface.+module Database.Relational.Monad.Trans.Qualify (+ -- * Qualify monad+ Qualify, qualify,+ evalQualifyPrime, qualifyQuery+ ) where++import Control.Monad.Trans.Class (lift)+import Control.Monad.Trans.State (StateT, runStateT, get, modify)+import Control.Applicative (Applicative)+import Control.Monad (liftM, ap)++import qualified Database.Relational.SqlSyntax as Syntax+++-- | Monad type to qualify SQL table forms.+newtype Qualify m a =+ Qualify (StateT Int m a)+ deriving (Monad, Functor, Applicative)++-- | Run qualify monad with initial state to get only result.+evalQualifyPrime :: Monad m => Qualify m a -> m a+evalQualifyPrime (Qualify s) = fst `liftM` runStateT s 0 {- primary alias id -}++-- | Generated new qualifier on internal state.+newAlias :: Monad m => Qualify m Syntax.Qualifier+newAlias = Qualify $ do+ ai <- Syntax.Qualifier `liftM` get+ modify (+ 1)+ return ai++-- | Lift to 'Qualify'+qualify :: Monad m => m a -> Qualify m a+qualify = Qualify . lift++-- | Get qualifyed table form query.+qualifyQuery :: Monad m+ => query -- ^ Query to qualify+ -> Qualify m (Syntax.Qualified query) -- ^ Result with updated state+qualifyQuery query =+ Syntax.qualify `liftM` newAlias `ap` return query
+ src/Database/Relational/Monad/Trans/Restricting.hs view
@@ -0,0 +1,72 @@+{-# LANGUAGE GeneralizedNewtypeDeriving #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Monad.Trans.Restricting+-- Copyright : 2014-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines monad transformer which lift to basic 'MonadQuery'.+module Database.Relational.Monad.Trans.Restricting (+ -- * Transformer into restricted context+ Restrictings, restrictings,++ -- * Result+ extractRestrict+ ) where++import Control.Monad.Trans.Class (MonadTrans (lift))+import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)+import Control.Applicative (Applicative, pure, (<$>))+import Control.Arrow (second)+import Data.DList (DList, toList)++import Database.Relational.SqlSyntax (Predicate)++import Database.Relational.Monad.Class+ (MonadQualify (..), MonadRestrict(..), MonadQuery (..), MonadAggregate(..))+++-- | Type to accumulate query restrictions.+-- Type 'c' is context tag of restriction building like+-- Flat (where) or Aggregated (having).+newtype Restrictings c m a =+ Restrictings (WriterT (DList (Predicate c)) m a)+ deriving (MonadTrans, Monad, Functor, Applicative)++-- | Lift to 'Restrictings'+restrictings :: Monad m => m a -> Restrictings c m a+restrictings = lift++-- | Add whole query restriction.+updateRestriction :: Monad m => Predicate c -> Restrictings c m ()+updateRestriction = Restrictings . tell . pure++-- | 'MonadRestrict' instance.+instance (Monad q, Functor q) => MonadRestrict c (Restrictings c q) where+ restrict = updateRestriction++-- | Restricted 'MonadQualify' instance.+instance MonadQualify q m => MonadQualify q (Restrictings c m) where+ liftQualify = restrictings . liftQualify++-- | Restricted 'MonadQuery' instance.+instance MonadQuery q => MonadQuery (Restrictings c q) where+ setDuplication = restrictings . setDuplication+ restrictJoin = restrictings . restrictJoin+ query' = restrictings . query'+ queryMaybe' = restrictings . queryMaybe'++-- | Resticted 'MonadAggregate' instance.+instance MonadAggregate m => MonadAggregate (Restrictings c m) where+ groupBy = restrictings . groupBy+ groupBy' = restrictings . groupBy'++-- | Run 'Restrictings' to get 'QueryRestriction'+extractRestrict :: (Monad m, Functor m) => Restrictings c m a -> m (a, [Predicate c])+extractRestrict (Restrictings rc) = second toList <$> runWriterT rc
+ src/Database/Relational/Monad/Type.hs view
@@ -0,0 +1,37 @@+-- |+-- Module : Database.Relational.Monad.Type+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines core query type.+module Database.Relational.Monad.Type+ ( -- * Core query monad+ QueryCore, extractCore,+ OrderedQuery,+ ) where++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Duplication, Record, JoinProduct, Predicate, )++import Database.Relational.Projectable (PlaceHolders)+import Database.Relational.Monad.BaseType (ConfigureQuery)+import Database.Relational.Monad.Trans.Join (QueryJoin, extractProduct)+import Database.Relational.Monad.Trans.Restricting (Restrictings, extractRestrict)+import Database.Relational.Monad.Trans.Ordering (Orderings)+++-- | Core query monad type used from flat(not-aggregated) query and aggregated query.+type QueryCore = Restrictings Flat (QueryJoin ConfigureQuery)++-- | Extract 'QueryCore' computation.+extractCore :: QueryCore a+ -> ConfigureQuery (((a, [Predicate Flat]), JoinProduct), Duplication)+extractCore = extractProduct . extractRestrict++-- | OrderedQuery monad type with placeholder type 'p'. Record must be the same as 'Orderings' context type parameter 'c'.+type OrderedQuery c m p r = Orderings c m (PlaceHolders p, Record c r)
+ src/Database/Relational/Monad/Unique.hs view
@@ -0,0 +1,59 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE GeneralizedNewtypeDeriving #-}++-- |+-- Module : Database.Relational.Monad.Unique+-- Copyright : 2014-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module contains definitions about unique query type+-- to support scalar queries.+module Database.Relational.Monad.Unique+ ( QueryUnique, unsafeUniqueSubQuery,+ toSubQuery,+ ) where++import Control.Applicative (Applicative)++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Duplication, Record, JoinProduct, NodeAttr,+ SubQuery, Predicate, Qualified, )++import qualified Database.Relational.Record as Record+import Database.Relational.Projectable (PlaceHolders)+import Database.Relational.Monad.Class (MonadQualify, MonadQuery)+import Database.Relational.Monad.Trans.Join (unsafeSubQueryWithAttr)+import Database.Relational.Monad.Trans.Restricting (restrictings)+import Database.Relational.Monad.BaseType (ConfigureQuery, askConfig)+import Database.Relational.Monad.Type (QueryCore, extractCore)+import Database.Relational.SqlSyntax (flatSubQuery)+++-- | Unique query monad type.+newtype QueryUnique a = QueryUnique (QueryCore a)+ deriving (MonadQualify ConfigureQuery, MonadQuery, Monad, Applicative, Functor)++-- | Unsafely join sub-query with this unique query.+unsafeUniqueSubQuery :: NodeAttr -- ^ Attribute maybe or just+ -> Qualified SubQuery -- ^ 'SubQuery' to join+ -> QueryUnique (Record c r) -- ^ Result joined context and record of 'SubQuery' result.+unsafeUniqueSubQuery a = QueryUnique . restrictings . unsafeSubQueryWithAttr a++extract :: QueryUnique a+ -> ConfigureQuery (((a, [Predicate Flat]), JoinProduct), Duplication)+extract (QueryUnique c) = extractCore c++-- | Run 'SimpleQuery' to get 'SubQuery' with 'Qualify' computation.+toSubQuery :: QueryUnique (PlaceHolders p, Record c r) -- ^ 'QueryUnique' to run+ -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'Qualify' computation+toSubQuery q = do+ ((((_ph, pj), rs), pd), da) <- extract q+ c <- askConfig+ return $ flatSubQuery c (Record.untype pj) da pd rs []
+ src/Database/Relational/Pi.hs view
@@ -0,0 +1,42 @@+-- |+-- Module : Database.Relational.Pi+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines typed projection path objects.+-- Contains normal interfaces.+module Database.Relational.Pi (+ -- * Projection path+ Pi, (<.>), (<?.>), (<?.?>),++ id', fst', snd'+ ) where++import qualified Control.Category as Category+import Database.Record+ (PersistableWidth, persistableWidth, PersistableRecordWidth)+import Database.Record.Persistable+ (runPersistableRecordWidth)++import Database.Relational.Pi.Unsafe+ (Pi, (<.>), (<?.>), (<?.?>), definePi)+++-- | Identity projection path.+id' :: Pi a a+id' = Category.id++-- | Projection path for fst of tuple.+fst' :: PersistableWidth a => Pi (a, b) a -- ^ Projection path of fst.+fst' = definePi 0++snd'' :: PersistableWidth b => PersistableRecordWidth a -> Pi (a, b) b+snd'' wa = definePi (runPersistableRecordWidth wa)++-- | Projection path for snd of tuple.+snd' :: (PersistableWidth a, PersistableWidth b) => Pi (a, b) b -- ^ Projection path of snd.+snd' = snd'' persistableWidth
+ src/Database/Relational/Pi/Unsafe.hs view
@@ -0,0 +1,182 @@+{-# LANGUAGE ExistentialQuantification #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Pi.Unsafe+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines typed projection path objects.+-- Contains internal structure and unsafe interfaces.+module Database.Relational.Pi.Unsafe (+ -- * Projection path+ Pi,++ width', width,++ (<.>), (<?.>), (<?.?>),++ pi,++ definePi, defineDirectPi', defineDirectPi,++ unsafeExpandIndexes',+ unsafeExpandIndexes+ ) where++import Prelude hiding (pi, (.), id)+import Control.Category (Category (..), (>>>))+import Data.Array (listArray, (!))+import Data.Functor.ProductIsomorphic+ (ProductIsoFunctor, (|$|), ProductIsoApplicative, pureP, (|*|),+ ProductIsoEmpty, pureE, peRight, peLeft, )++import Database.Record.Persistable+ (PersistableRecordWidth, runPersistableRecordWidth, unsafePersistableRecordWidth,+ PersistableWidth (persistableWidth), maybeWidth)+++-- | Projection path primary structure type.+data Pi' r0 r1 = Leftest Int+ | Map [Int]++unsafePiAppend' :: Pi' a b' -> Pi' b c' -> Pi' a c+unsafePiAppend' = d where+ d (Leftest i) (Leftest j) = Leftest $ i + j+ d (Leftest i) (Map js) = Map $ map (i +) js+ d (Map is) (Leftest j) = Map $ drop j is+ d (Map is) (Map js) = Map [ is' ! j | j <- js ] where+ is' = listArray (0, length is) is++-- | Projection path from type 'r0' into type 'r1'.+-- This type also indicate key object which type is 'r1' for record type 'r0'.+newtype Pi r0 r1 = Pi { runPi :: PersistableRecordWidth r0 -> (Pi' r0 r1, PersistableRecordWidth r1) }++instance PersistableWidth r0 => Show (Pi r0 r1) where+ show p = unwords ["Pi", show $ unsafeExpandIndexes p]++unsafePiAppend :: (PersistableRecordWidth b' -> PersistableRecordWidth b)+ -> (PersistableRecordWidth c' -> PersistableRecordWidth c)+ -> Pi a b' -> Pi b c' -> Pi a c+unsafePiAppend wbf wcf (Pi f) (Pi g) = Pi $ \wa ->+ let (pab, wb) = f wa+ (pbc, wc) = g $ wbf wb+ in (pab `unsafePiAppend'` pbc, wcf wc)++-- | Unsafely untype key to expand indexes.+unsafeExpandIndexes' :: PersistableRecordWidth a -> Pi a b -> [Int]+unsafeExpandIndexes' wa (Pi f) = d $ f wa where+ d (Map is, _) = is+ d (Leftest i, w) = [ i .. i + w' - 1 ] where+ w' = runPersistableRecordWidth w++-- | Unsafely untype key to expand indexes.+unsafeExpandIndexes :: PersistableWidth a => Pi a b -> [Int]+unsafeExpandIndexes = unsafeExpandIndexes' persistableWidth++-- | Unsafely cast width proof object of record. Result record must be same width.+unsafeCastRecordWidth :: PersistableRecordWidth a -> PersistableRecordWidth a'+unsafeCastRecordWidth = unsafePersistableRecordWidth . runPersistableRecordWidth++unsafeCast :: Pi a b' -> Pi a b+unsafeCast = c where+ d (Leftest i) = Leftest i+ d (Map m) = Map m+ c (Pi f) = Pi $ \wa ->+ let (pb, wb) = f wa in+ (d pb, unsafeCastRecordWidth wb)++-- | 'Pi' with zero width which projects to unit+pzero :: Pi a ()+pzero = Pi $ \_ -> (Map [], persistableWidth)++-- | Map projection path 'Pi' which has record result type.+instance ProductIsoFunctor (Pi a) where+ _ |$| p = unsafeCast p++-- | Compose projection path 'Pi' which has record result type using applicative style.+instance ProductIsoApplicative (Pi a) where+ pureP _ = unsafeCast pzero+ pab |*| pb =+ Pi $ \wr ->+ let (_, wab) = runPi pab wr+ (_, wb) = runPi pb wr in+ (Map $ unsafeExpandIndexes' wr pab ++ unsafeExpandIndexes' wr pb,+ wab |*| wb)++instance ProductIsoEmpty (Pi a) () where+ pureE = pzero+ peRight = unsafeCast+ peLeft = unsafeCast++-- | Get record width proof object.+width' :: PersistableWidth r => Pi r ct -> PersistableRecordWidth ct+width' (Pi f) = snd $ f persistableWidth++-- | Get record width.+width :: PersistableWidth r => Pi r a -> Int+width = runPersistableRecordWidth . width'++justWidth :: PersistableRecordWidth (Maybe a) -> PersistableRecordWidth a+justWidth = unsafeCastRecordWidth+++instance Category Pi where+ id = Pi $ \pw -> (Leftest 0, pw)+ Pi fb . Pi fa = Pi $ \wa ->+ let (pb, wb) = fa wa+ (pc, wc) = fb wb+ in (unsafePiAppend' pb pc, wc)++-- | Compose projection path.+(<.>) :: Pi a b -> Pi b c -> Pi a c+(<.>) = (>>>)++-- | Compose projection path. 'Maybe' phantom functor is 'map'-ed.+(<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)+(<?.>) = unsafePiAppend justWidth maybeWidth++-- | Compose projection path. 'Maybe' phantom functors are 'join'-ed like '>=>'.+(<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)+(<?.?>) = unsafePiAppend justWidth id++infixl 8 <.>, <?.>, <?.?>++-- | Unsafely project untyped value list.+pi :: PersistableRecordWidth r0 -> Pi r0 r1 -> [a] -> [a]+pi w0 (Pi f) cs = d p' where+ (p', w1) = f w0+ d (Leftest i) = take (runPersistableRecordWidth w1) . drop i $ cs+ d (Map is) = [cs' ! i | i <- is]+ cs' = listArray (0, length cs) cs++-- | Unsafely define projection path from type 'r0' into type 'r1'.+definePi' :: PersistableRecordWidth r1+ -> Int -- ^ Index of flat SQL value list+ -> Pi r0 r1 -- ^ Result projection path+definePi' pw i = Pi $ \_ -> (Leftest i, pw)++-- | Unsafely define projection path from type 'r0' into type 'r1'.+-- Use inferred 'PersistableRecordWidth'.+definePi :: PersistableWidth r1+ => Int -- ^ Index of flat SQL value list+ -> Pi r0 r1 -- ^ Result projection path+definePi = definePi' persistableWidth++-- | Unsafely define projection path from type 'r0' into type 'r1'.+defineDirectPi' :: PersistableRecordWidth r1+ -> [Int] -- ^ Indexes of flat SQL value list+ -> Pi r0 r1 -- ^ Result projection path+defineDirectPi' pw is = Pi $ \_ -> (Map is, pw)++-- | Unsafely define projection path from type 'r0' into type 'r1'.+-- Use inferred 'PersistableRecordWidth'.+defineDirectPi :: PersistableWidth r1+ => [Int] -- ^ Indexes of flat SQL value list+ -> Pi r0 r1 -- ^ Result projection path+defineDirectPi = defineDirectPi' persistableWidth
+ src/Database/Relational/Projectable.hs view
@@ -0,0 +1,539 @@+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module : Database.Relational.Projectable+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines operators on various projected records.+module Database.Relational.Projectable (+ -- * Projectable from SQL strings+ SqlContext (unsafeProjectSqlTerms), unsafeProjectSql',+ unsafeProjectSql,++ -- * Records of values+ value,+ valueTrue, valueFalse,+ values,+ nothing,++ -- * Placeholders+ PlaceHolders, unsafeAddPlaceHolders, unsafePlaceHolders,+ pwPlaceholder, placeholder', placeholder, unitPlaceHolder, unitPH,++ -- * Projectable into SQL strings+ unsafeShowSql', unsafeShowSql,++ -- * Operators+ (.=.), (.<.), (.<=.), (.>.), (.>=.), (.<>.),++ and', or', in',++ (.||.), (?||?), like, likeMaybe, like', likeMaybe',+ (.+.), (.-.), (.*.), (./.),+ (?+?), (?-?), (?*?), (?/?),++ isNothing, isJust, fromMaybe,+ not', exists,++ negate', fromIntegral', showNum,+ negateMaybe, fromIntegralMaybe, showNumMaybe,++ casesOrElse, casesOrElse',+ caseSearch, caseSearchMaybe, case', caseMaybe,++ SqlBinOp, unsafeBinOp, unsafeUniOp,++ -- * Terms for Window function types+ rank, denseRank, rowNumber, percentRank, cumeDist,++ -- * Zipping projections+ projectZip, (><),++ -- * 'Maybe' type projecitoins+ ProjectableMaybe (just, flattenMaybe),+ ) where++import Prelude hiding (pi)++import Data.String (IsString)+import Data.Functor.ProductIsomorphic+ (ProductIsoFunctor, (|$|), ProductIsoApplicative, pureP, (|*|),+ ProductIsoEmpty, pureE, peRight, peLeft, )++import Language.SQL.Keyword (Keyword)+import qualified Language.SQL.Keyword as SQL++import Database.Record+ (PersistableWidth, persistableWidth, PersistableRecordWidth,+ HasColumnConstraint, NotNull)+import Database.Record.Persistable (runPersistableRecordWidth)++import Database.Relational.Internal.ContextType+ (Flat, Aggregated, Exists, OverWindow)+import Database.Relational.Internal.String (StringSQL, stringSQL, showStringSQL)+import Database.Relational.SqlSyntax (Record, Predicate)+import qualified Database.Relational.SqlSyntax as Syntax++import Database.Relational.Pure ()+import Database.Relational.TupleInstances ()+import Database.Relational.ProjectableClass+ (ShowConstantTermsSQL, showConstantTermsSQL, )+import Database.Relational.Record (RecordList)+import qualified Database.Relational.Record as Record+++-- | Interface to project SQL terms unsafely.+class SqlContext c where+ -- | Unsafely project from SQL expression terms.+ unsafeProjectSqlTerms :: [StringSQL]+ -> Record c t++-- | Unsafely make 'Record' from SQL terms.+instance SqlContext Flat where+ unsafeProjectSqlTerms = Record.unsafeFromSqlTerms++-- | Unsafely make 'Record' from SQL terms.+instance SqlContext Aggregated where+ unsafeProjectSqlTerms = Record.unsafeFromSqlTerms++-- | Unsafely make 'Record' from SQL terms.+instance SqlContext OverWindow where+ unsafeProjectSqlTerms = Record.unsafeFromSqlTerms++class SqlContext c => OperatorContext c+instance OperatorContext Flat+instance OperatorContext Aggregated+++-- | Unsafely Project single SQL term.+unsafeProjectSql' :: SqlContext c => StringSQL -> Record c t+unsafeProjectSql' = unsafeProjectSqlTerms . (:[])++-- | Unsafely Project single SQL string. String interface of 'unsafeProjectSql'''.+unsafeProjectSql :: SqlContext c => String -> Record c t+unsafeProjectSql = unsafeProjectSql' . stringSQL++-- | Record with polymorphic phantom type of SQL null value. Semantics of comparing is unsafe.+nothing :: (OperatorContext c, SqlContext c, PersistableWidth a)+ => Record c (Maybe a)+nothing = proxyWidth persistableWidth+ where+ proxyWidth :: SqlContext c => PersistableRecordWidth a -> Record c (Maybe a)+ proxyWidth w = unsafeProjectSqlTerms $ replicate (runPersistableRecordWidth w) SQL.NULL++-- | Generate record with polymorphic type of SQL constant values from Haskell value.+value :: (ShowConstantTermsSQL t, OperatorContext c) => t -> Record c t+value = unsafeProjectSqlTerms . showConstantTermsSQL++-- | Record with polymorphic type of SQL true value.+valueTrue :: (OperatorContext c, ProjectableMaybe (Record c)) => Record c (Maybe Bool)+valueTrue = just $ value True++-- | Record with polymorphic type of SQL false value.+valueFalse :: (OperatorContext c, ProjectableMaybe (Record c)) => Record c (Maybe Bool)+valueFalse = just $ value False++-- | RecordList with polymorphic type of SQL set value from Haskell list.+values :: (ShowConstantTermsSQL t, OperatorContext c) => [t] -> RecordList (Record c) t+values = Record.list . map value+++-- | Unsafely generate SQL expression term from record object.+unsafeShowSql' :: Record c a -> StringSQL+unsafeShowSql' = Record.unsafeStringSql++-- | Unsafely generate SQL expression string from record object.+-- String interface of 'unsafeShowSql''.+unsafeShowSql :: Record c a -- ^ Source record object+ -> String -- ^ Result SQL expression string.+unsafeShowSql = showStringSQL . unsafeShowSql'+++-- | Binary operator type for SQL String.+type SqlBinOp = Keyword -> Keyword -> Keyword++-- | Unsafely make unary operator for records from SQL keyword.+unsafeUniOp :: SqlContext c2+ => (Keyword -> Keyword) -> Record c1 a -> Record c2 b+unsafeUniOp u = unsafeProjectSql' . u . unsafeShowSql'++unsafeFlatUniOp :: SqlContext c+ => Keyword -> Record c a -> Record c b+unsafeFlatUniOp kw = unsafeUniOp (SQL.paren . SQL.defineUniOp kw)++-- | Unsafely make binary operator for records from string binary operator.+unsafeBinOp :: SqlContext k+ => SqlBinOp+ -> Record k a -> Record k b -> Record k c+unsafeBinOp op a b = unsafeProjectSql' . SQL.paren $+ op (unsafeShowSql' a) (unsafeShowSql' b)++-- | Unsafely make binary operator to compare records from string binary operator.+compareBinOp :: SqlContext c+ => SqlBinOp+ -> Record c a -> Record c a -> Record c (Maybe Bool)+compareBinOp = unsafeBinOp++-- | Unsafely make numrical binary operator for records from string binary operator.+monoBinOp :: SqlContext c+ => SqlBinOp+ -> Record c a -> Record c a -> Record c a+monoBinOp = unsafeBinOp+++-- | Compare operator corresponding SQL /=/ .+(.=.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.=.) = compareBinOp (SQL..=.)++-- | Compare operator corresponding SQL /</ .+(.<.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.<.) = compareBinOp (SQL..<.)++-- | Compare operator corresponding SQL /<=/ .+(.<=.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.<=.) = compareBinOp (SQL..<=.)++-- | Compare operator corresponding SQL />/ .+(.>.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.>.) = compareBinOp (SQL..>.)++-- | Compare operator corresponding SQL />=/ .+(.>=.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.>=.) = compareBinOp (SQL..>=.)++-- | Compare operator corresponding SQL /<>/ .+(.<>.) :: OperatorContext c+ => Record c ft -> Record c ft -> Record c (Maybe Bool)+(.<>.) = compareBinOp (SQL..<>.)++-- | Logical operator corresponding SQL /AND/ .+and' :: OperatorContext c+ => Record c (Maybe Bool) -> Record c (Maybe Bool) -> Record c (Maybe Bool)+and' = monoBinOp SQL.and++-- | Logical operator corresponding SQL /OR/ .+or' :: OperatorContext c+ => Record c (Maybe Bool) -> Record c (Maybe Bool) -> Record c (Maybe Bool)+or' = monoBinOp SQL.or++-- | Logical operator corresponding SQL /NOT/ .+not' :: OperatorContext c+ => Record c (Maybe Bool) -> Record c (Maybe Bool)+not' = unsafeFlatUniOp SQL.NOT++-- | Logical operator corresponding SQL /EXISTS/ .+exists :: OperatorContext c+ => RecordList (Record Exists) r -> Record c (Maybe Bool)+exists = unsafeProjectSql' . SQL.paren . SQL.defineUniOp SQL.EXISTS+ . Record.unsafeStringSqlList unsafeShowSql'++-- | Concatinate operator corresponding SQL /||/ .+(.||.) :: OperatorContext c+ => Record c a -> Record c a -> Record c a+(.||.) = unsafeBinOp (SQL..||.)++-- | Concatinate operator corresponding SQL /||/ . Maybe type version.+(?||?) :: (OperatorContext c, IsString a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)+(?||?) = unsafeBinOp (SQL..||.)++unsafeLike :: OperatorContext c+ => Record c a -> Record c b -> Record c (Maybe Bool)+unsafeLike = unsafeBinOp (SQL.defineBinOp SQL.LIKE)++-- | String-compare operator corresponding SQL /LIKE/ .+like' :: (OperatorContext c, IsString a)+ => Record c a -> Record c a -> Record c (Maybe Bool)+x `like'` y = x `unsafeLike` y++-- | String-compare operator corresponding SQL /LIKE/ .+likeMaybe' :: (OperatorContext c, IsString a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe Bool)+x `likeMaybe'` y = x `unsafeLike` y++-- | String-compare operator corresponding SQL /LIKE/ .+like :: (OperatorContext c, IsString a, ShowConstantTermsSQL a)+ => Record c a -> a -> Record c (Maybe Bool)+x `like` a = x `like'` value a++-- | String-compare operator corresponding SQL /LIKE/ . Maybe type version.+likeMaybe :: (OperatorContext c, IsString a, ShowConstantTermsSQL a)+ => Record c (Maybe a) -> a -> Record c (Maybe Bool)+x `likeMaybe` a = x `unsafeLike` value a++-- | Unsafely make number binary operator for records from SQL operator string.+monoBinOp' :: SqlContext c+ => Keyword -> Record c a -> Record c a -> Record c a+monoBinOp' = monoBinOp . SQL.defineBinOp++-- | Number operator corresponding SQL /+/ .+(.+.) :: (OperatorContext c, Num a)+ => Record c a -> Record c a -> Record c a+(.+.) = monoBinOp' "+"++-- | Number operator corresponding SQL /-/ .+(.-.) :: (OperatorContext c, Num a)+ => Record c a -> Record c a -> Record c a+(.-.) = monoBinOp' "-"++-- | Number operator corresponding SQL /// .+(./.) :: (OperatorContext c, Num a)+ => Record c a -> Record c a -> Record c a+(./.) = monoBinOp' "/"++-- | Number operator corresponding SQL /*/ .+(.*.) :: (OperatorContext c, Num a)+ => Record c a -> Record c a -> Record c a+(.*.) = monoBinOp' "*"++-- | Number negate uni-operator corresponding SQL /-/.+negate' :: (OperatorContext c, Num a)+ => Record c a -> Record c a+negate' = unsafeFlatUniOp $ SQL.word "-"++unsafeCastProjectable :: SqlContext c+ => Record c a -> Record c b+unsafeCastProjectable = unsafeProjectSql' . unsafeShowSql'++-- | Number fromIntegral uni-operator.+fromIntegral' :: (SqlContext c, Integral a, Num b)+ => Record c a -> Record c b+fromIntegral' = unsafeCastProjectable++-- | Unsafely show number into string-like type in records.+showNum :: (SqlContext c, Num a, IsString b)+ => Record c a -> Record c b+showNum = unsafeCastProjectable++-- | Number operator corresponding SQL /+/ .+(?+?) :: (OperatorContext c, Num a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)+(?+?) = monoBinOp' "+"++-- | Number operator corresponding SQL /-/ .+(?-?) :: (OperatorContext c, Num a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)+(?-?) = monoBinOp' "-"++-- | Number operator corresponding SQL /// .+(?/?) :: (OperatorContext c, Num a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)+(?/?) = monoBinOp' "/"++-- | Number operator corresponding SQL /*/ .+(?*?) :: (OperatorContext c, Num a)+ => Record c (Maybe a) -> Record c (Maybe a) -> Record c (Maybe a)+(?*?) = monoBinOp' "*"++-- | Number negate uni-operator corresponding SQL /-/.+negateMaybe :: (OperatorContext c, Num a)+ => Record c (Maybe a) -> Record c (Maybe a)+negateMaybe = unsafeFlatUniOp $ SQL.word "-"++-- | Number fromIntegral uni-operator.+fromIntegralMaybe :: (SqlContext c, Integral a, Num b)+ => Record c (Maybe a) -> Record c (Maybe b)+fromIntegralMaybe = unsafeCastProjectable++-- | Unsafely show number into string-like type in records.+showNumMaybe :: (SqlContext c, Num a, IsString b)+ => Record c (Maybe a) -> Record c (Maybe b)+showNumMaybe = unsafeCastProjectable++-- | Search case operator correnponding SQL search /CASE/.+-- Like, /CASE WHEN p0 THEN a WHEN p1 THEN b ... ELSE c END/+caseSearch :: OperatorContext c+ => [(Predicate c, Record c a)] -- ^ Each when clauses+ -> Record c a -- ^ Else result record+ -> Record c a -- ^ Result record+caseSearch = Syntax.caseSearch++-- | Same as 'caseSearch', but you can write like <when list> `casesOrElse` <else clause>.+casesOrElse :: OperatorContext c+ => [(Predicate c, Record c a)] -- ^ Each when clauses+ -> Record c a -- ^ Else result record+ -> Record c a -- ^ Result record+casesOrElse = caseSearch++-- | Null default version of 'caseSearch'.+caseSearchMaybe :: (OperatorContext c {- (Record c) is always ProjectableMaybe -}, PersistableWidth a)+ => [(Predicate c, Record c (Maybe a))] -- ^ Each when clauses+ -> Record c (Maybe a) -- ^ Result record+caseSearchMaybe cs = caseSearch cs nothing++-- | Simple case operator correnponding SQL simple /CASE/.+-- Like, /CASE x WHEN v THEN a WHEN w THEN b ... ELSE c END/+case' :: OperatorContext c+ => Record c a -- ^ Record value to match+ -> [(Record c a, Record c b)] -- ^ Each when clauses+ -> Record c b -- ^ Else result record+ -> Record c b -- ^ Result record+case' = Syntax.case'++-- | Uncurry version of 'case'', and you can write like ... `casesOrElse'` <else clause>.+casesOrElse' :: OperatorContext c+ => (Record c a, [(Record c a, Record c b)]) -- ^ Record value to match and each when clauses list+ -> Record c b -- ^ Else result record+ -> Record c b -- ^ Result record+casesOrElse' = uncurry case'++-- | Null default version of 'case''.+caseMaybe :: (OperatorContext c {- (Record c) is always ProjectableMaybe -}, PersistableWidth b)+ => Record c a -- ^ Record value to match+ -> [(Record c a, Record c (Maybe b))] -- ^ Each when clauses+ -> Record c (Maybe b) -- ^ Result record+caseMaybe v cs = case' v cs nothing++-- | Binary operator corresponding SQL /IN/ .+in' :: OperatorContext c+ => Record c t -> RecordList (Record c) t -> Record c (Maybe Bool)+in' a lp = unsafeProjectSql' . SQL.paren+ $ SQL.in' (unsafeShowSql' a) (Record.unsafeStringSqlList unsafeShowSql' lp)++-- | Operator corresponding SQL /IS NULL/ , and extended against record types.+isNothing :: (OperatorContext c, HasColumnConstraint NotNull r)+ => Record c (Maybe r) -> Predicate c+isNothing mr = unsafeProjectSql' $+ SQL.paren $ (SQL.defineBinOp SQL.IS)+ (Record.unsafeStringSqlNotNullMaybe mr) SQL.NULL++-- | Operator corresponding SQL /NOT (... IS NULL)/ , and extended against record type.+isJust :: (OperatorContext c, HasColumnConstraint NotNull r)+ => Record c (Maybe r) -> Predicate c+isJust = not' . isNothing++-- | Operator from maybe type using record extended 'isNull'.+fromMaybe :: (OperatorContext c, HasColumnConstraint NotNull r)+ => Record c r -> Record c (Maybe r) -> Record c r+fromMaybe d p = [ (isNothing p, d) ] `casesOrElse` unsafeCastProjectable p++unsafeUniTermFunction :: SqlContext c => Keyword -> Record c t+unsafeUniTermFunction = unsafeProjectSql' . (SQL.<++> stringSQL "()")++-- | /RANK()/ term.+rank :: Integral a => Record OverWindow a+rank = unsafeUniTermFunction SQL.RANK++-- | /DENSE_RANK()/ term.+denseRank :: Integral a => Record OverWindow a+denseRank = unsafeUniTermFunction SQL.DENSE_RANK++-- | /ROW_NUMBER()/ term.+rowNumber :: Integral a => Record OverWindow a+rowNumber = unsafeUniTermFunction SQL.ROW_NUMBER++-- | /PERCENT_RANK()/ term.+percentRank :: Record OverWindow Double+percentRank = unsafeUniTermFunction SQL.PERCENT_RANK++-- | /CUME_DIST()/ term.+cumeDist :: Record OverWindow Double+cumeDist = unsafeUniTermFunction SQL.CUME_DIST++-- | Placeholder parameter type which has real parameter type arguemnt 'p'.+data PlaceHolders p = PlaceHolders++-- | Unsafely add placeholder parameter to queries.+unsafeAddPlaceHolders :: Functor f => f a -> f (PlaceHolders p, a)+unsafeAddPlaceHolders = fmap ((,) PlaceHolders)++-- | Unsafely get placeholder parameter+unsafePlaceHolders :: PlaceHolders p+unsafePlaceHolders = PlaceHolders++-- | No placeholder semantics+unitPlaceHolder :: PlaceHolders ()+unitPlaceHolder = pureP ()++-- | No placeholder semantics. Same as `unitPlaceHolder`+unitPH :: PlaceHolders ()+unitPH = pureP ()++-- | Unsafely cast placeholder parameter type.+unsafeCastPlaceHolders :: PlaceHolders a -> PlaceHolders b+unsafeCastPlaceHolders PlaceHolders = PlaceHolders++-- | Provide scoped placeholder from width and return its parameter object.+pwPlaceholder :: SqlContext c+ => PersistableRecordWidth a+ -> (Record c a -> b)+ -> (PlaceHolders a, b)+pwPlaceholder pw f = (PlaceHolders, f $ projectPlaceHolder pw)+ where+ projectPlaceHolder :: SqlContext c+ => PersistableRecordWidth a+ -> Record c a+ projectPlaceHolder = unsafeProjectSqlTerms . (`replicate` "?") . runPersistableRecordWidth++-- | Provide scoped placeholder and return its parameter object.+placeholder' :: (PersistableWidth t, SqlContext c) => (Record c t -> a) -> (PlaceHolders t, a)+placeholder' = pwPlaceholder persistableWidth++-- | Provide scoped placeholder and return its parameter object. Monadic version.+placeholder :: (PersistableWidth t, SqlContext c, Monad m) => (Record c t -> m a) -> m (PlaceHolders t, a)+placeholder f = do+ let (ph, ma) = placeholder' f+ a <- ma+ return (ph, a)+++-- | Zipping projections.+projectZip :: ProductIsoApplicative p => p a -> p b -> p (a, b)+projectZip pa pb = (,) |$| pa |*| pb++-- | Binary operator the same as 'projectZip'.+(><) :: ProductIsoApplicative p => p a -> p b -> p (a, b)+(><) = projectZip++-- | Interface to control 'Maybe' of phantom type in records.+class ProjectableMaybe p where+ -- | Cast record phantom type into 'Maybe'.+ just :: p a -> p (Maybe a)+ -- | Compose nested 'Maybe' phantom type on record.+ flattenMaybe :: p (Maybe (Maybe a)) -> p (Maybe a)++-- | Control phantom 'Maybe' type in placeholder parameters.+instance ProjectableMaybe PlaceHolders where+ just = unsafeCastPlaceHolders+ flattenMaybe = unsafeCastPlaceHolders++-- | Control phantom 'Maybe' type in record type 'Record'.+instance ProjectableMaybe (Record c) where+ just = Record.just+ flattenMaybe = Record.flattenMaybe++-- | Zipping except for identity element laws against placeholder parameter type.+instance ProductIsoEmpty PlaceHolders () where+ pureE = unsafePlaceHolders+ peRight = unsafeCastPlaceHolders+ peLeft = unsafeCastPlaceHolders++-- | Compose seed of record type 'PlaceHolders'.+instance ProductIsoFunctor PlaceHolders where+ _ |$| PlaceHolders = PlaceHolders++-- | Compose record type 'PlaceHolders' using applicative style.+instance ProductIsoApplicative PlaceHolders where+ pureP _ = unsafeCastPlaceHolders unitPH+ pf |*| pa = unsafeCastPlaceHolders (pf >< pa)++infixl 7 .*., ./., ?*?, ?/?+infixl 6 .+., .-., ?+?, ?-?+infixl 5 .||., ?||?+infix 4 .=., .<>., .>., .>=., .<., .<=., `in'`, `like`, `likeMaybe`, `like'`, `likeMaybe'`+infixr 3 `and'`+infixr 2 `or'`+infixl 1 ><
+ src/Database/Relational/ProjectableClass.hs view
@@ -0,0 +1,73 @@+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE TypeOperators #-}+{-# LANGUAGE DefaultSignatures #-}++-- |+-- Module : Database.Relational.ProjectableClass+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides interfaces to preserve constraints of+-- direct product projections.+module Database.Relational.ProjectableClass (+ -- * Literal SQL terms+ ShowConstantTermsSQL (..), showConstantTermsSQL,+ StringSQL,++ ) where++import GHC.Generics (Generic, Rep, U1 (..), K1 (..), M1 (..), (:*:)(..), from)+import Data.Monoid (mempty, (<>))+import Data.DList (DList, toList)++import Database.Relational.Internal.String (StringSQL)+++-- | Convert from haskell record to SQL terms list.+showConstantTermsSQL :: ShowConstantTermsSQL a+ => a+ -> [StringSQL]+showConstantTermsSQL = toList . showConstantTermsSQL'++{- |+'ShowConstantTermsSQL' 'a' is implicit rule to derive function to convert+from haskell record type 'a' into constant SQL terms.++Generic programming (<https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#generic-programming>)+with default signature is available for 'ShowConstantTermsSQL' class,+so you can make instance like below:++@+ \{\-\# LANGUAGE DeriveGeneric \#\-\}+ import GHC.Generics (Generic)+ --+ data Foo = Foo { ... } deriving Generic+ instance ShowConstantTermsSQL Foo+@++-}+class ShowConstantTermsSQL a where+ showConstantTermsSQL' :: a -> DList StringSQL++ default showConstantTermsSQL' :: (Generic a, GShowConstantTermsSQL (Rep a)) => a -> DList StringSQL+ showConstantTermsSQL' = gShowConstantTermsSQL . from++class GShowConstantTermsSQL f where+ gShowConstantTermsSQL :: f a -> DList StringSQL++instance GShowConstantTermsSQL U1 where+ gShowConstantTermsSQL U1 = mempty++instance (GShowConstantTermsSQL a, GShowConstantTermsSQL b) =>+ GShowConstantTermsSQL (a :*: b) where+ gShowConstantTermsSQL (a :*: b) = gShowConstantTermsSQL a <> gShowConstantTermsSQL b++instance GShowConstantTermsSQL a => GShowConstantTermsSQL (M1 i c a) where+ gShowConstantTermsSQL (M1 a) = gShowConstantTermsSQL a++instance ShowConstantTermsSQL a => GShowConstantTermsSQL (K1 i a) where+ gShowConstantTermsSQL (K1 a) = showConstantTermsSQL' a
+ src/Database/Relational/ProjectableExtended.hs view
@@ -0,0 +1,168 @@+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Module : Database.Relational.ProjectableExtended+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines operators on various projected records.+module Database.Relational.ProjectableExtended (+ -- * Projection for nested 'Maybe's+ ProjectableFlattenMaybe (flatten),++ flattenPiMaybe,++ -- * Get narrower records+ (!), (?!), (?!?), (!??),++ -- * Aggregate functions+ unsafeAggregateOp,+ count,+ sum', sumMaybe, avg, avgMaybe,+ max', maxMaybe, min', minMaybe,+ every, any', some',+ ) where++import Prelude hiding (pi)++import qualified Language.SQL.Keyword as SQL+import Database.Record (PersistableWidth)++import Database.Relational.Internal.ContextType (Flat, Aggregated, OverWindow)+import Database.Relational.SqlSyntax (Predicate, Record, )++import qualified Database.Relational.Record as Record+import Database.Relational.Projectable+ (unsafeUniOp, ProjectableMaybe (flattenMaybe), SqlContext)+import Database.Relational.Pi (Pi)+++class AggregatedContext ac+instance AggregatedContext Aggregated+instance AggregatedContext OverWindow++-- | Unsafely make aggregation uni-operator from SQL keyword.+unsafeAggregateOp :: (AggregatedContext ac, SqlContext ac)+ => SQL.Keyword -> Record Flat a -> Record ac b+unsafeAggregateOp op = unsafeUniOp ((op SQL.<++>) . SQL.paren)++-- | Aggregation function COUNT.+count :: (Integral b, AggregatedContext ac, SqlContext ac)+ => Record Flat a -> Record ac b+count = unsafeAggregateOp SQL.COUNT++-- | Aggregation function SUM.+sumMaybe :: (Num a, AggregatedContext ac, SqlContext ac)+ => Record Flat (Maybe a) -> Record ac (Maybe a)+sumMaybe = unsafeAggregateOp SQL.SUM++-- | Aggregation function SUM.+sum' :: (Num a, AggregatedContext ac, SqlContext ac)+ => Record Flat a -> Record ac (Maybe a)+sum' = sumMaybe . Record.just++-- | Aggregation function AVG.+avgMaybe :: (Num a, Fractional b, AggregatedContext ac, SqlContext ac)+ => Record Flat (Maybe a) -> Record ac (Maybe b)+avgMaybe = unsafeAggregateOp SQL.AVG++-- | Aggregation function AVG.+avg :: (Num a, Fractional b, AggregatedContext ac, SqlContext ac)+ => Record Flat a -> Record ac (Maybe b)+avg = avgMaybe . Record.just++-- | Aggregation function MAX.+maxMaybe :: (Ord a, AggregatedContext ac, SqlContext ac)+ => Record Flat (Maybe a) -> Record ac (Maybe a)+maxMaybe = unsafeAggregateOp SQL.MAX++-- | Aggregation function MAX.+max' :: (Ord a, AggregatedContext ac, SqlContext ac)+ => Record Flat a -> Record ac (Maybe a)+max' = maxMaybe . Record.just++-- | Aggregation function MIN.+minMaybe :: (Ord a, AggregatedContext ac, SqlContext ac)+ => Record Flat (Maybe a) -> Record ac (Maybe a)+minMaybe = unsafeAggregateOp SQL.MIN++-- | Aggregation function MIN.+min' :: (Ord a, AggregatedContext ac, SqlContext ac)+ => Record Flat a -> Record ac (Maybe a)+min' = minMaybe . Record.just++-- | Aggregation function EVERY.+every :: (AggregatedContext ac, SqlContext ac)+ => Predicate Flat -> Record ac (Maybe Bool)+every = unsafeAggregateOp SQL.EVERY++-- | Aggregation function ANY.+any' :: (AggregatedContext ac, SqlContext ac)+ => Predicate Flat -> Record ac (Maybe Bool)+any' = unsafeAggregateOp SQL.ANY++-- | Aggregation function SOME.+some' :: (AggregatedContext ac, SqlContext ac)+ => Predicate Flat -> Record ac (Maybe Bool)+some' = unsafeAggregateOp SQL.SOME++-- | Get narrower record along with projection path.+(!) :: PersistableWidth a+ => Record c a -- ^ Source 'Record'+ -> Pi a b -- ^ Record path+ -> Record c b -- ^ Narrower projected object+(!) = Record.pi++-- | Get narrower record along with projection path+-- 'Maybe' phantom functor is 'map'-ed.+(?!) :: PersistableWidth a+ => Record c (Maybe a) -- ^ Source 'Record'. 'Maybe' type+ -> Pi a b -- ^ Record path+ -> Record c (Maybe b) -- ^ Narrower projected object. 'Maybe' type result+(?!) = Record.piMaybe++-- | Get narrower record along with projection path+-- and project into result record type.+-- Source record 'Maybe' phantom functor and projection path leaf 'Maybe' functor are 'join'-ed.+(?!?) :: PersistableWidth a+ => Record c (Maybe a) -- ^ Source 'Record'. 'Maybe' phantom type+ -> Pi a (Maybe b) -- ^ Record path. 'Maybe' type leaf+ -> Record c (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result+(?!?) = Record.piMaybe'+++-- | Interface to compose phantom 'Maybe' nested type.+class ProjectableFlattenMaybe a b where+ flatten :: ProjectableMaybe p => p a -> p b++-- | Compose 'Maybe' type in record phantom type.+instance ProjectableFlattenMaybe (Maybe a) b+ => ProjectableFlattenMaybe (Maybe (Maybe a)) b where+ flatten = flatten . flattenMaybe++-- | Not 'Maybe' type is not processed.+instance ProjectableFlattenMaybe (Maybe a) (Maybe a) where+ flatten = id++-- | Get narrower record with flatten leaf phantom Maybe types along with projection path.+flattenPiMaybe :: (PersistableWidth a, ProjectableMaybe (Record cont), ProjectableFlattenMaybe (Maybe b) c)+ => Record cont (Maybe a) -- ^ Source 'Record'. 'Maybe' phantom type+ -> Pi a b -- ^ Projection path+ -> Record cont c -- ^ Narrower 'Record'. Flatten 'Maybe' phantom type+flattenPiMaybe p = flatten . Record.piMaybe p++-- | Get narrower record with flatten leaf phantom Maybe types along with projection path.+(!??) :: (PersistableWidth a, ProjectableMaybe (Record cont), ProjectableFlattenMaybe (Maybe b) c)+ => Record cont (Maybe a) -- ^ Source 'Record'. 'Maybe' phantom type+ -> Pi a b -- ^ Projection path+ -> Record cont c -- ^ Narrower flatten and projected object.+(!??) = flattenPiMaybe+++infixl 8 !, ?!, ?!?, !??
+ src/Database/Relational/Pure.hs view
@@ -0,0 +1,160 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleInstances #-}++-- |+-- Module : Database.Relational.Pure+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines interfaces between haskell pure values+-- and query internal record values.+module Database.Relational.Pure () where++import Control.Applicative (pure)+import Data.Monoid ((<>))+import Data.Int (Int8, Int16, Int32, Int64)+import Data.ByteString (ByteString)+import qualified Data.ByteString.Lazy as LB+import Data.Text (Text)+import qualified Data.Text as T+import qualified Data.Text.Encoding as T+import qualified Data.Text.Lazy as LT+import qualified Data.Text.Lazy.Encoding as LT+import Text.Printf (PrintfArg, printf)+import Data.Time (FormatTime, Day, TimeOfDay, LocalTime, UTCTime, ZonedTime, formatTime)+import Data.Time.Locale.Compat (defaultTimeLocale)+import Data.DList (DList, fromList)++import Language.SQL.Keyword (Keyword (..))+import Database.Record+ (PersistableWidth, persistableWidth, PersistableRecordWidth)+import Database.Record.Persistable+ (runPersistableRecordWidth)++import Database.Relational.Internal.String (StringSQL, stringSQL, boolSQL)++import Database.Relational.ProjectableClass (ShowConstantTermsSQL (..))+++-- | Constant integral SQL terms.+intTermsSQL :: (Show a, Integral a) => a -> DList StringSQL+intTermsSQL = pure . stringSQL . show++-- | Escape 'String' for constant SQL string expression.+escapeStringToSqlExpr :: String -> String+escapeStringToSqlExpr = rec where+ rec "" = ""+ rec ('\'':cs) = '\'' : '\'' : rec cs+ rec (c:cs) = c : rec cs++-- | From 'String' into constant SQL string expression.+stringExprSQL :: String -> StringSQL+stringExprSQL = stringSQL . ('\'':) . (++ "'") . escapeStringToSqlExpr++stringTermsSQL :: String -> DList StringSQL+stringTermsSQL = pure . stringExprSQL++-- | Constant SQL terms of '()'.+instance ShowConstantTermsSQL ()++-- | Constant SQL terms of 'Int8'.+instance ShowConstantTermsSQL Int8 where+ showConstantTermsSQL' = intTermsSQL++-- | Constant SQL terms of 'Int16'.+instance ShowConstantTermsSQL Int16 where+ showConstantTermsSQL' = intTermsSQL++-- | Constant SQL terms of 'Int32'.+instance ShowConstantTermsSQL Int32 where+ showConstantTermsSQL' = intTermsSQL++-- | Constant SQL terms of 'Int64'.+instance ShowConstantTermsSQL Int64 where+ showConstantTermsSQL' = intTermsSQL++-- | Constant SQL terms of 'Int'.+-- Use this carefully, because this is architecture dependent size of integer type.+instance ShowConstantTermsSQL Int where+ showConstantTermsSQL' = intTermsSQL++-- | Constant SQL terms of 'String'.+instance ShowConstantTermsSQL String where+ showConstantTermsSQL' = stringTermsSQL++-- | Constant SQL terms of 'ByteString'.+instance ShowConstantTermsSQL ByteString where+ showConstantTermsSQL' = stringTermsSQL . T.unpack . T.decodeUtf8++-- | Constant SQL terms of 'LB.ByteString'.+instance ShowConstantTermsSQL LB.ByteString where+ showConstantTermsSQL' = stringTermsSQL . LT.unpack . LT.decodeUtf8++-- | Constant SQL terms of 'Text'.+instance ShowConstantTermsSQL Text where+ showConstantTermsSQL' = stringTermsSQL . T.unpack++-- | Constant SQL terms of 'LT.Text'.+instance ShowConstantTermsSQL LT.Text where+ showConstantTermsSQL' = stringTermsSQL . LT.unpack++-- | Constant SQL terms of 'Char'.+instance ShowConstantTermsSQL Char where+ showConstantTermsSQL' = stringTermsSQL . (:"")++-- | Constant SQL terms of 'Bool'.+instance ShowConstantTermsSQL Bool where+ showConstantTermsSQL' = pure . boolSQL++floatTerms :: (PrintfArg a, Ord a, Num a)=> a -> DList StringSQL+floatTerms f = pure . stringSQL $ printf fmt f where+ fmt+ | f >= 0 = "%f"+ | otherwise = "(%f)"++-- | Constant SQL terms of 'Float'. Caution for floating-point error rate.+instance ShowConstantTermsSQL Float where+ showConstantTermsSQL' = floatTerms++-- | Constant SQL terms of 'Double'. Caution for floating-point error rate.+instance ShowConstantTermsSQL Double where+ showConstantTermsSQL' = floatTerms++constantTimeTerms :: FormatTime t => Keyword -> String -> t -> DList StringSQL+constantTimeTerms kw fmt t = pure $ kw <> stringExprSQL (formatTime defaultTimeLocale fmt t)++-- | Constant SQL terms of 'Day'.+instance ShowConstantTermsSQL Day where+ showConstantTermsSQL' = constantTimeTerms DATE "%Y-%m-%d"++-- | Constant SQL terms of 'TimeOfDay'.+instance ShowConstantTermsSQL TimeOfDay where+ showConstantTermsSQL' = constantTimeTerms TIME "%H:%M:%S"++-- | Constant SQL terms of 'LocalTime'.+instance ShowConstantTermsSQL LocalTime where+ showConstantTermsSQL' = constantTimeTerms TIMESTAMP "%Y-%m-%d %H:%M:%S"++-- | Constant SQL terms of 'ZonedTime'.+-- This generates ***NOT STANDARD*** SQL of TIMESTAMPTZ literal.+instance ShowConstantTermsSQL ZonedTime where+ showConstantTermsSQL' = constantTimeTerms TIMESTAMPTZ "%Y-%m-%d %H:%M:%S%z"++-- | Constant SQL terms of 'UTCTime'.+-- This generates ***NOT STANDARD*** SQL of TIMESTAMPTZ literal with UTC timezone.+instance ShowConstantTermsSQL UTCTime where+ showConstantTermsSQL' = constantTimeTerms TIMESTAMPTZ "%Y-%m-%d %H:%M:%S%z"++showMaybeTerms :: ShowConstantTermsSQL a => PersistableRecordWidth a -> Maybe a -> DList StringSQL+showMaybeTerms wa = d where+ d (Just a) = showConstantTermsSQL' a+ d Nothing = fromList . replicate (runPersistableRecordWidth wa) $ stringSQL "NULL"++-- | Constant SQL terms of 'Maybe' type. Width inference is required.+instance (PersistableWidth a, ShowConstantTermsSQL a)+ => ShowConstantTermsSQL (Maybe a) where+ showConstantTermsSQL' = showMaybeTerms persistableWidth
src/Database/Relational/Query.hs view
@@ -1,94 +1,19 @@ -- | -- Module : Database.Relational.Query--- Copyright : 2013-2017 Kei Hibino+-- Copyright : 2017 Kei Hibino -- License : BSD3 -- -- Maintainer : ex8k.hibino@gmail.com -- Stability : experimental -- Portability : unknown ----- This module is integrated module of Query.-module Database.Relational.Query (- module Database.Relational.Query.Table,- module Database.Relational.Query.SQL,- module Database.Relational.Query.Pi,- module Database.Relational.Query.Constraint,- module Database.Relational.Query.Context,- module Database.Relational.Query.Component,- module Database.Relational.Query.Sub,- module Database.Relational.Query.Projection,- module Database.Relational.Query.ProjectableClass,- module Database.Relational.Query.Projectable,- module Database.Relational.Query.ProjectableExtended,- module Database.Relational.Query.TupleInstances,- module Database.Relational.Query.Monad.BaseType,- module Database.Relational.Query.Monad.Class,- module Database.Relational.Query.Monad.Trans.Ordering,- module Database.Relational.Query.Monad.Trans.Aggregating,- module Database.Relational.Query.Monad.Trans.Assigning,- module Database.Relational.Query.Monad.Type,- module Database.Relational.Query.Monad.Simple,- module Database.Relational.Query.Monad.Aggregate,- module Database.Relational.Query.Monad.Restrict,- module Database.Relational.Query.Monad.Unique,- module Database.Relational.Query.Monad.Assign,- module Database.Relational.Query.Monad.Register,- module Database.Relational.Query.Relation,- module Database.Relational.Query.Scalar,- module Database.Relational.Query.Type,- module Database.Relational.Query.Effect,- module Database.Relational.Query.Derives- ) where--import Database.Relational.Query.Table (Table, TableDerivable (..))-import Database.Relational.Query.SQL (QuerySuffix, updateOtherThanKeySQL, insertSQL)-import Database.Relational.Query.Pure ()-import Database.Relational.Query.Pi-import Database.Relational.Query.Constraint- (Key, tableConstraint, projectionKey,- uniqueKey, -- notNullKey,- HasConstraintKey(constraintKey),- derivedUniqueKey, -- derivedNotNullKey,- Primary, Unique, NotNull)-import Database.Relational.Query.Context-import Database.Relational.Query.Component- (NameConfig (..), SchemaNameMode (..), ProductUnitSupport (..), IdentifierQuotation (..),- Config (..), defaultConfig,- AggregateKey, Order (..), Nulls (..))-import Database.Relational.Query.Sub (SubQuery, unitSQL, queryWidth)-import Database.Relational.Query.Projection (Projection, list)-import Database.Relational.Query.ProjectableClass-import Database.Relational.Query.Projectable-import Database.Relational.Query.ProjectableExtended-import Database.Relational.Query.TupleInstances-import Database.Relational.Query.Monad.BaseType-import Database.Relational.Query.Monad.Class- (MonadQualify,- MonadRestrict, wheres, having, restrict,- MonadAggregate, groupBy, groupBy',- MonadQuery, query', queryMaybe',- MonadPartition, partitionBy,- distinct, all', on)-import Database.Relational.Query.Monad.Trans.Ordering (orderBy', orderBy, asc, desc)-import Database.Relational.Query.Monad.Trans.Aggregating- (key, key', set, bkey, rollup, cube, groupingSets)-import Database.Relational.Query.Monad.Trans.Assigning (assignTo, (<-#))-import Database.Relational.Query.Monad.Type-import Database.Relational.Query.Monad.Simple (QuerySimple, SimpleQuery)-import Database.Relational.Query.Monad.Aggregate- (QueryAggregate, AggregatedQuery, Window, over)-import Database.Relational.Query.Monad.Restrict (Restrict)-import Database.Relational.Query.Monad.Unique (QueryUnique)-import Database.Relational.Query.Monad.Assign (Assign)-import Database.Relational.Query.Monad.Register (Register)-import Database.Relational.Query.Relation-import Database.Relational.Query.Scalar (ScalarDegree)-import Database.Relational.Query.Type hiding- (unsafeTypedKeyUpdate, unsafeTypedDelete,- unsafeTypedInsert, unsafeTypedInsertQuery, )-import Database.Relational.Query.Effect-import Database.Relational.Query.Derives--import Database.Record.Instances ()+-- This module contains backword compatibility interface of+-- relational-query <= 0.9.*+module Database.Relational.Query+ {-# DEPRECATED "Should switch namespace to Database.Relational" #-}+ ( module Database.Relational,+ module Database.Relational.Compat,+ ) where -{-# ANN module "HLint: ignore Use import/export shortcut" #-}+import Database.Relational hiding (unsafeShowSql', unsafeShowSql, unsafeProjectSqlTerms, unsafeProjectSql)+import Database.Relational.Compat
src/Database/Relational/Query/Arrow.hs view
@@ -1,448 +1,19 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}- -- | -- Module : Database.Relational.Query.Arrow--- Copyright : 2015-2017 Kei Hibino+-- Copyright : 2017 Kei Hibino -- License : BSD3 -- -- Maintainer : ex8k.hibino@gmail.com -- Stability : experimental -- Portability : unknown ----- This module defines arrow version combinators which--- improves type-safty on building queries.--- Referencing the local projections may cause to break--- the result query.--- It is possible to controls injection of previous local projections--- by restricting domain type of arrow. This idea is imported from Opaleye:------ * <https://github.com/tomjaguarpaw/haskell-opaleye>--- * <https://github.com/khibino/haskell-relational-record/issues/19>------ Importing this module instead of "Database.Relational.Query" enables--- to build query using arrow combinators.-module Database.Relational.Query.Arrow (- module Database.Relational.Query,-- all', distinct,-- query, queryMaybe, query', queryMaybe',- queryList, queryList', queryExists, queryExists', queryListU, queryListU',- queryScalar, queryScalar', queryScalarU, queryScalarU',-- uniqueQuery', uniqueQueryMaybe',-- on, wheres, having, groupBy, placeholder,-- relation, relation', aggregateRelation, aggregateRelation',-- uniqueRelation',-- groupBy', key, key', set, bkey, rollup, cube, groupingSets,-- orderBy', orderBy, asc, desc,-- partitionBy, over,-- assign,-- derivedUpdate', derivedUpdate,- derivedInsertValue', derivedInsertValue,- derivedDelete', derivedDelete,-- QueryA,-- QuerySimple, QueryAggregate, QueryUnique,-- AggregatingSet, AggregatingSetList, AggregatingPowerSet,-- Orderings, Window, Assignings,-- AssignStatement, Register, RestrictedStatement,- ) where--import Control.Category (Category)-import Control.Arrow (Arrow, Kleisli (..))--import Database.Record--import Database.Relational.Query hiding- (all', distinct,- query, queryMaybe, query', queryMaybe',- queryList, queryList', queryScalar, queryScalar',- uniqueQuery', uniqueQueryMaybe',- on, wheres, having, groupBy, placeholder,- relation, relation', aggregateRelation, aggregateRelation', uniqueRelation',- groupBy', key, key', set, bkey, rollup, cube, groupingSets,- orderBy', orderBy, asc, desc, partitionBy, over,- derivedUpdate', derivedUpdate,- derivedInsertValue', derivedInsertValue,- derivedDelete', derivedDelete,- QuerySimple, QueryAggregate, QueryUnique, Window, Register)-import qualified Database.Relational.Query as Monadic-import Database.Relational.Query.Projection (ListProjection)-import qualified Database.Relational.Query.Monad.Trans.Aggregating as Monadic-import qualified Database.Relational.Query.Monad.Trans.Ordering as Monadic-import qualified Database.Relational.Query.Monad.Trans.Assigning as Monadic----- | Arrow to build queries.-newtype QueryA m a b = QueryA (Kleisli m a b) deriving (Category, Arrow)--queryA :: (a -> m b) -> QueryA m a b-queryA = QueryA . Kleisli--runQueryA :: QueryA m a b -> a -> m b-runQueryA (QueryA k) = runKleisli k--runAofM :: (m b -> c) -> QueryA m () b -> c-runAofM = (. (`runQueryA` ()))---- | Arrow type corresponding to 'Monadic.QuerySimple'-type QuerySimple = QueryA Monadic.QuerySimple---- | Arrow type corresponding to 'Monadic.QueryAggregate'-type QueryAggregate = QueryA Monadic.QueryAggregate---- | Arrow type corresponding to 'Monadic.QueryUnique'-type QueryUnique = QueryA Monadic.QueryUnique---- | Arrow type corresponding to 'Monadic.AggregatingSet'-type AggregatingSet = QueryA Monadic.AggregatingSet---- | Arrow type corresponding to 'Monadic.AggregatingSetList'-type AggregatingSetList = QueryA Monadic.AggregatingSetList---- | Arrow type corresponding to 'Monadic.AggregatingPowerSet'-type AggregatingPowerSet = QueryA Monadic.AggregatingPowerSet---- | Arrow type corresponding to 'Monadic.Orderings'-type Orderings c m = QueryA (Monadic.Orderings c m)---- | Arrow type corresponding to 'Monadic.Window'-type Window c = QueryA (Monadic.Window c)---- | Arrow type corresponding to 'Monadic.Assignings'-type Assignings r m = QueryA (Monadic.Assignings r m)---- | Arrow type corresponding to 'Monadic.AssignStatement'-type AssignStatement r a = Assignings r Restrict (Projection Flat r) a---- | Arrow type corresponding to 'Monadic.Register'-type Register r a = QueryA (Monadic.Register r) () a---- | Arrow type corresponding to 'Monadic.RestrictedStatement'-type RestrictedStatement r a = QueryA Monadic.Restrict (Projection Flat r) a----- | Same as 'Monadic.all''. Arrow version.-all' :: MonadQuery m => QueryA m () ()-all' = queryA $ \() -> Monadic.all'---- | Same as 'Monadic.distinct'. Arrow version.-distinct :: MonadQuery m => QueryA m () ()-distinct = queryA $ \() -> Monadic.distinct---- | Same as 'Monadic.query'. Arrow version.--- The result arrow is not injected by local projections.-query :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation () r -> QueryA m () (Projection Flat r)-query r = queryA $ \() -> Monadic.query r---- | Same as 'Monadic.queryMaybe'. Arrow version.--- The result arrow is not injected by any local projections.-queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation () r -> QueryA m () (Projection Flat (Maybe r))-queryMaybe r = queryA $ \() -> Monadic.queryMaybe r---- | Same as 'Monadic.query''. Arrow version.--- The result arrow is not injected by any local projections.-query' :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation p r -> QueryA m () (PlaceHolders p, Projection Flat r)-query' r = queryA $ \() -> Monadic.query' r---- | Same as 'Monadic.queryMaybe''. Arrow version.--- The result arrow is not injected by any local projections.-queryMaybe' :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation p r -> QueryA m () (PlaceHolders p, Projection Flat (Maybe r))-queryMaybe' r = queryA $ \() -> Monadic.queryMaybe' r--unsafeQueryList :: MonadQualify ConfigureQuery m- => (a -> Relation () r)- -> QueryA m a (ListProjection (Projection c) r)-unsafeQueryList rf = queryA $ Monadic.queryList . rf--unsafeQueryList' :: MonadQualify ConfigureQuery m- => (a -> Relation p r)- -> QueryA m a (PlaceHolders p, ListProjection (Projection c) r)-unsafeQueryList' rf = queryA $ Monadic.queryList' . rf---- | Same as 'Monadic.queryList'. Arrow version.--- The result arrow is designed to be injected by local projections.-queryList :: MonadQualify ConfigureQuery m- => (Projection c a -> Relation () r)- -> QueryA m (Projection c a) (ListProjection (Projection c) r)-queryList = unsafeQueryList---- | Same as 'Monadic.queryList''. Arrow version.--- The result arrow is designed to be injected by local projections.-queryList' :: MonadQualify ConfigureQuery m- => (Projection c a -> Relation p r)- -> QueryA m (Projection c a) (PlaceHolders p, ListProjection (Projection c) r)-queryList' = unsafeQueryList'---- | Same as 'Monadic.queryList' to pass this result to 'exists' operator. Arrow version.--- The result arrow is designed to be injected by local projections.-queryExists :: MonadQualify ConfigureQuery m- => (Projection c a -> Relation () r)- -> QueryA m (Projection c a) (ListProjection (Projection Exists) r)-queryExists = unsafeQueryList---- | Same as 'Monadic.queryList'' to pass this result to 'exists' operator. Arrow version.--- The result arrow is designed to be injected by local projections.-queryExists' :: MonadQualify ConfigureQuery m- => (Projection c a -> Relation p r)- -> QueryA m (Projection c a) (PlaceHolders p, ListProjection (Projection Exists) r)-queryExists' = unsafeQueryList'---- | Same as 'Monadic.queryList'. Arrow version.--- Useful for no reference cases to local projections.-queryListU :: MonadQualify ConfigureQuery m- => Relation () r- -> QueryA m () (ListProjection (Projection c) r)-queryListU r = unsafeQueryList $ \() -> r---- | Same as 'Monadic.queryList''. Arrow version.--- Useful for no reference cases to local projections.-queryListU' :: MonadQualify ConfigureQuery m- => Relation p r- -> QueryA m () (PlaceHolders p, ListProjection (Projection c) r)-queryListU' r = unsafeQueryList' $ \() -> r--unsafeQueryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => (a -> UniqueRelation () c r)- -> QueryA m a (Projection c (Maybe r))-unsafeQueryScalar rf = queryA $ Monadic.queryScalar . rf--unsafeQueryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => (a -> UniqueRelation p c r)- -> QueryA m a (PlaceHolders p, Projection c (Maybe r))-unsafeQueryScalar' rf = queryA $ Monadic.queryScalar' . rf---- | Same as 'Monadic.queryScalar'. Arrow version.--- The result arrow is designed to be injected by any local projection.-queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => (Projection c a -> UniqueRelation () c r)- -> QueryA m (Projection c a) (Projection c (Maybe r))-queryScalar = unsafeQueryScalar---- | Same as 'Monadic.queryScalar''. Arrow version.--- The result arrow is designed to be injected by any local projection.-queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => (Projection c a -> UniqueRelation p c r)- -> QueryA m (Projection c a) (PlaceHolders p, Projection c (Maybe r))-queryScalar' = unsafeQueryScalar'---- | Same as 'Monadic.queryScalar'. Arrow version.--- Useful for no reference cases to local projections.-queryScalarU :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => UniqueRelation () c r- -> QueryA m () (Projection c (Maybe r))-queryScalarU r = unsafeQueryScalar $ \() -> r---- | Same as 'Monadic.queryScalar''. Arrow version.--- Useful for no reference cases to local projections.-queryScalarU' :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => UniqueRelation p c r- -> QueryA m () (PlaceHolders p, Projection c (Maybe r))-queryScalarU' r = unsafeQueryScalar' $ \() -> r---- | Same as 'Monadic.uniqueQuery''. Arrow version.--- The result arrow is not injected by local projections.-uniqueQuery' :: UniqueRelation p c r- -> QueryA Monadic.QueryUnique () (PlaceHolders p, Projection c r)-uniqueQuery' r = queryA $ \() -> Monadic.uniqueQuery' r---- | Same as 'Monadic.uniqueQueryMaybe''. Arrow version.--- The result arrow is not injected by local projections.-uniqueQueryMaybe' :: UniqueRelation p c r- -> QueryA Monadic.QueryUnique () (PlaceHolders p, Projection c (Maybe r))-uniqueQueryMaybe' r = queryA $ \() -> Monadic.uniqueQueryMaybe' r---- | Same as 'Monadic.on'. Arrow version.--- The result arrow is designed to be injected by local conditional flat-projections.-on :: MonadQuery m- => QueryA m (Projection Flat (Maybe Bool)) ()-on = queryA Monadic.on---- | Same as 'Monadic.wheres'. Arrow version.--- The result arrow is designed to be injected by local conditional flat-projections.-wheres :: MonadRestrict Flat m- => QueryA m (Projection Flat (Maybe Bool)) ()-wheres = queryA Monadic.wheres---- | Same as 'Monadic.having'. Arrow version.--- The result arrow is designed to be injected by local conditional aggregated-projections.-having :: MonadRestrict Aggregated m- => QueryA m (Projection Aggregated (Maybe Bool)) ()-having = queryA Monadic.having---- | Same as 'Monadic.groupBy'. Arrow version.--- The result arrow is designed to be injected by local flat-projections.-groupBy :: MonadAggregate m- => QueryA m (Projection Flat r) (Projection Aggregated r)-groupBy = queryA Monadic.groupBy---- | Same as 'Monadic.placeholder'. Arrow version.--- The result arrow is designed to be injected by locally built arrow using placeholders.-placeholder :: (PersistableWidth t, SqlProjectable p, Monad m)- => QueryA m (QueryA m (p t) a) (PlaceHolders t, a)-placeholder = queryA $ Monadic.placeholder . runQueryA---- | Same as 'Monadic.relation'.--- Finalize query-building arrow instead of query-building monad.-relation :: QuerySimple () (Projection Flat r)- -> Relation () r-relation = runAofM Monadic.relation---- | Same as 'Monadic.relation''.--- Finalize query-building arrow instead of query-building monad.-relation' :: QuerySimple () (PlaceHolders p, Projection Flat r)- -> Relation p r-relation' = runAofM Monadic.relation'---- | Same as 'Monadic.aggregateRelation'.--- Finalize query-building arrow instead of query-building monad.-aggregateRelation :: QueryAggregate () (Projection Aggregated r)- -> Relation () r-aggregateRelation = runAofM Monadic.aggregateRelation---- | Same as 'Monadic.aggregateRelation''.--- Finalize query-building arrow instead of query-building monad.-aggregateRelation' :: QueryAggregate () (PlaceHolders p, Projection Aggregated r)- -> Relation p r-aggregateRelation' = runAofM Monadic.aggregateRelation'---- | Same as 'Monadic.uniqueRelation''.--- Finalize query-building arrow instead of query-building monad.-uniqueRelation' :: QueryUnique () (PlaceHolders p, Projection c r)- -> UniqueRelation p c r-uniqueRelation' = runAofM Monadic.uniqueRelation'---- | Same as 'Monadic.groupBy''.--- This arrow is designed to be injected by local 'AggregateKey'.-groupBy' :: MonadAggregate m => QueryA m (AggregateKey (Projection Aggregated r)) (Projection Aggregated r)-groupBy' = queryA Monadic.groupBy'---- | Same as 'Monadic.key'.--- This arrow is designed to be injected by local flat-projections.-key :: AggregatingSet (Projection Flat r) (Projection Aggregated (Maybe r))-key = queryA Monadic.key---- | Same as 'Monadic.key''.--- This arrow is designed to be injected by local 'AggregteKey'.-key' :: AggregatingSet (AggregateKey a) a-key' = queryA Monadic.key'---- | Same as 'Monadic.set'.--- This arrow is designed to be injected by locally built 'AggregtingSet' arrow.-set :: AggregatingSetList (AggregatingSet () a) a-set = queryA $ runAofM Monadic.set---- | Same as 'Monadic.bkey'.--- This arrow is designed to be injected by local flat-projections.-bkey :: AggregatingPowerSet (Projection Flat r) (Projection Aggregated (Maybe r))-bkey = queryA Monadic.bkey---- | Same as 'Monadic.rollup'.--- Finalize locally built 'AggregatingPowerSet'.-rollup :: AggregatingPowerSet () a -> AggregateKey a-rollup = runAofM Monadic.rollup---- | Same as 'Monadic.cube'.--- Finalize locally built 'AggregatingPowerSet'.-cube :: AggregatingPowerSet () a -> AggregateKey a-cube = runAofM Monadic.cube---- | Same as 'Monadic.groupingSets'.--- Finalize locally built 'AggregatingSetList'.-groupingSets :: AggregatingSetList () a -> AggregateKey a-groupingSets = runAofM Monadic.groupingSets---- | Same as 'Monadic.orderBy''.--- The result arrow is designed to be injected by local projections.-orderBy' :: Monad m- => Order- -> Nulls- -> Orderings c m (Projection c t) ()-orderBy' o n = queryA $ \p -> Monadic.orderBy' p o n---- | Same as 'Monadic.orderBy'.--- The result arrow is designed to be injected by local projections.-orderBy :: Monad m- => Order- -> Orderings c m (Projection c t) ()-orderBy o = queryA (`Monadic.orderBy` o)---- | Same as 'Monadic.asc'.--- The result arrow is designed to be injected by local projections.-asc :: Monad m- => Orderings c m (Projection c t) ()-asc = queryA Monadic.asc---- | Same as 'Monadic.desc'.--- The result arrow is designed to be injected by local projections.-desc :: Monad m- => Orderings c m (Projection c t) ()-desc = queryA Monadic.desc---- | Same as 'Monadic.partitionBy'.--- The result arrow is designed to be injected by local projections.-partitionBy :: Window c (Projection c r) ()-partitionBy = queryA Monadic.partitionBy---- | Same as 'Monadic.over'.--- Make window function result projection using built 'Window' arrow.-over :: SqlProjectable (Projection c)- => Projection OverWindow a -> Window c () () -> Projection c a-over po = runAofM $ Monadic.over po--infix 8 `over`---- | Make 'Monadic.AssignTarget' into arrow which is designed to be--- injected by local projection assignees.-assign :: Monad m- => Monadic.AssignTarget r v- -> Assignings r m (Projection Flat v) ()-assign t = queryA (`Monadic.assignTo` t)---- | Same as 'Monadic.derivedUpdate''.--- Make 'Update' from assigning statement arrow using configuration.-derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p-derivedUpdate' config = Monadic.derivedUpdate' config . runQueryA---- | Same as 'Monadic.derivedUpdate'.--- Make 'Update' from assigning statement arrow.-derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p-derivedUpdate = Monadic.derivedUpdate . runQueryA---- | Same as 'Monadic.derivedInsertValue''.--- Make 'Insert' from register arrow using configuration.-derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p-derivedInsertValue' config = Monadic.derivedInsertValue' config . ($ ()) . runQueryA---- | Same as 'Monadic.derivedInsertValue'.--- Make 'Insert' from register arrow.-derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p-derivedInsertValue = Monadic.derivedInsertValue . ($ ()) . runQueryA---- | Same as 'Monadic.derivedDelete''.--- Make 'Update' from restrict statement arrow using configuration.-derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p-derivedDelete' config = Monadic.derivedDelete' config . runQueryA+-- This module contains backword compatibility interface of+-- relational-query <= 0.9.*+module Database.Relational.Query.Arrow+ {-# DEPRECATED "Should switch namespace to Database.Relational.Arrow" #-}+ ( module Database.Relational.Arrow,+ module Database.Relational.Compat,+ ) where --- | Same as 'Monadic.derivedDelete'.--- Make 'Update' from restrict statement arrow.-derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p-derivedDelete = Monadic.derivedDelete . runQueryA+import Database.Relational.Arrow hiding (unsafeShowSql', unsafeShowSql, unsafeProjectSqlTerms, unsafeProjectSql)+import Database.Relational.Compat
− src/Database/Relational/Query/BaseTH.hs
@@ -1,85 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ConstraintKinds #-}---- |--- Module : Database.Relational.Query.BaseTH--- Copyright : 2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines templates for internally using.-module Database.Relational.Query.BaseTH (- defineProductConstructorInstance,- defineTupleProductConstructor,- defineTupleShowConstantInstance,- defineTuplePi,- ) where--import Control.Applicative ((<$>))-import Data.List (foldl')-import Language.Haskell.TH- (Q, Name, mkName, tupleDataName, normalB, classP, varP,- TypeQ, forallT, arrowT, varT, tupleT, appT,- Dec, sigD, valD, instanceD, ExpQ, conE,- TyVarBndr (PlainTV), )-import Database.Record.Persistable- (PersistableWidth, persistableWidth,- PersistableRecordWidth, runPersistableRecordWidth)--import Database.Relational.Query.ProjectableClass- (ProductConstructor (..), ShowConstantTermsSQL (..), )-import Database.Relational.Query.Pi.Unsafe (Pi, definePi)----- | Make template for 'ProductConstructor' instance.-defineProductConstructorInstance :: TypeQ -> ExpQ -> [TypeQ] -> Q [Dec]-defineProductConstructorInstance recTypeQ recData colTypes =- [d| instance ProductConstructor $(foldr (appT . (arrowT `appT`)) recTypeQ colTypes) where- productConstructor = $(recData)- |]--tupleN :: Int -> (([Name], [TypeQ]), TypeQ)-tupleN n = ((ns, vs), foldl' appT (tupleT n) vs)- where- ns = [ mkName $ "a" ++ show j | j <- [1 .. n] ]- vs = map varT ns---- | Make template of ProductConstructor instance of tuple type.-defineTupleProductConstructor :: Int -> Q [Dec]-defineTupleProductConstructor n = do- let ((_, vs), tty) = tupleN n- defineProductConstructorInstance tty (conE $ tupleDataName n) vs---- | Make template of 'ShowConstantTermsSQL' instance of tuple type.-defineTupleShowConstantInstance :: Int -> Q [Dec]-defineTupleShowConstantInstance n = do- let ((_, vs), tty) = tupleN n- (:[]) <$> instanceD- -- in template-haskell 2.8 or older, Pred is not Type- (mapM (classP ''ShowConstantTermsSQL . (:[])) vs)- [t| ShowConstantTermsSQL $tty |]- []--tuplePi :: Int -> Int -> Q [Dec]-tuplePi n i = do- let selN = mkName $ "tuplePi" ++ show n ++ "_" ++ show i ++ "'"- ((ns, vs), tty) = tupleN n- sig <- sigD selN $- forallT (map PlainTV ns)- (mapM (classP ''PersistableWidth . (:[])) vs)- [t| Pi $tty $(vs !! i) |]- val <- valD (varP selN)- (normalB [| definePi $(foldl'- (\e t -> [| $e + runPersistableRecordWidth (persistableWidth :: PersistableRecordWidth $t) |])- [| 0 :: Int |] $ take i vs) |])- []- return [sig, val]---- | Make templates of projection paths for tuple types.-defineTuplePi :: Int -> Q [Dec]-defineTuplePi n =- concat <$> mapM (tuplePi n) [0 .. n - 1]
− src/Database/Relational/Query/Component.hs
@@ -1,27 +0,0 @@--- |--- Module : Database.Relational.Query.Component--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides untyped components for query.-module Database.Relational.Query.Component- ( -- * Configuration type for query- module Database.Relational.Query.Internal.Config,-- -- * Types for aggregation- AggregateKey,-- -- * Types for ordering- Order (..), Nulls (..),- ) where--import Database.Relational.Query.Internal.Config- (NameConfig (..),- ProductUnitSupport (..), SchemaNameMode (..), IdentifierQuotation (..),- Config (..), defaultConfig,)-import Database.Relational.Query.Internal.BaseSQL (Order (..), Nulls (..),)-import Database.Relational.Query.Internal.GroupingSQL (AggregateKey)
− src/Database/Relational/Query/Constraint.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.Constraint--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides proof object definitions of constraint key.--- Difference between this module and "Database.Record.KeyConstraint" is--- typed constraint key column definition is included in this module.-module Database.Relational.Query.Constraint (- -- * Constraint Key proof object- Key, indexes, unsafeDefineConstraintKey,- tableConstraint, projectionKey,-- -- unsafeReturnKey, -- unsafeAppendConstraint,-- -- * Derivation rules- uniqueKey, -- notNullKey,-- -- * Inference rules- HasConstraintKey (..),- derivedUniqueKey, -- derivedNotNullKey,-- -- * Constraint types- Primary, Unique, NotNull- ) where---import Database.Record (PersistableRecordWidth, PersistableWidth (persistableWidth))-import Database.Record.KeyConstraint- (KeyConstraint, unsafeSpecifyKeyConstraint,- Primary, Unique, NotNull)-import qualified Database.Record.KeyConstraint as C--import Database.Relational.Query.Pi (Pi)-import qualified Database.Relational.Query.Pi.Unsafe as UnsafePi----- | Constraint Key proof object. Constraint type 'c', record type 'r' and columns type 'ct'.-data Key c r ct = Key [Int] (PersistableRecordWidth ct)---- | Index of key which specifies constraint key.-indexes :: Key c r ct -> [Int]-indexes (Key is _) = is---- | Width of key.-width :: Key c r ct -> PersistableRecordWidth ct-width (Key _ w) = w---- | Unsafely generate constraint 'Key' proof object using specified key index.-unsafeDefineConstraintKey :: PersistableWidth ct- => [Int] -- ^ Key indexes which specify this constraint key- -> Key c r ct -- ^ Result constraint key proof object-unsafeDefineConstraintKey ixs = Key ixs persistableWidth---- | Get table constraint 'KeyConstraint' proof object from constraint 'Key'.-tableConstraint :: Key c r ct -> KeyConstraint c r-tableConstraint = unsafeSpecifyKeyConstraint . indexes---- | Get projection path proof object from constraint 'Key'.-projectionKey :: Key c r ct -> Pi r ct-projectionKey k = UnsafePi.defineDirectPi' w ixs where- ixs = indexes k- w = width k---- | Unsafe. Make constraint key to add column phantom type-unsafeReturnKey :: PersistableWidth ct- => KeyConstraint c r -> Key c r ct-unsafeReturnKey = unsafeDefineConstraintKey . C.indexes---- -- | Unsafe. Make constraint key to add constraint phantom type--- unsafeAppendConstraint :: Pi r ct -> Key c r ct--- unsafeAppendConstraint = unsafeDefineConstraintKey . leafIndex----- | Map from table constraint into constraint 'Key'.-mapConstraint :: PersistableWidth ct- => (KeyConstraint c0 r -> KeyConstraint c1 r)- -> Key c0 r ct- -> Key c1 r ct-mapConstraint f = unsafeReturnKey . f . tableConstraint---- | Derive 'Unique' constraint 'Key' from 'Primary' constraint 'Key'-uniqueKey :: PersistableWidth ct- => Key Primary r ct -> Key Unique r ct-uniqueKey = mapConstraint C.unique---- -- | Derive 'NotNull' constraint 'Key' from 'Primary' constraint 'Key'--- notNullKey :: Key Primary r ct -> Key NotNull r ct--- notNullKey = mapConstraint C.notNull----- | Constraint 'Key' inference interface.-class PersistableWidth ct => HasConstraintKey c r ct where- -- | Infer constraint key.- constraintKey :: Key c r ct---- | Inferred 'Unique' constraint 'Key'.--- Record type 'r' has unique key which type is 'ct' derived from primay key.-derivedUniqueKey :: HasConstraintKey Primary r ct => Key Unique r ct-derivedUniqueKey = uniqueKey constraintKey---- -- | Inferred 'NotNull' constraint 'Key'.--- -- Record type 'r' has not-null key which type is 'ct' derived from primay key.--- derivedNotNullKey :: HasConstraintKey Primary r ct => Key NotNull r ct--- derivedNotNullKey = notNullKey constraintKey
− src/Database/Relational/Query/Context.hs
@@ -1,15 +0,0 @@--- |--- Module : Database.Relational.Query.Context--- Copyright : 2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module re-export query context tag types.-module Database.Relational.Query.Context- ( module Database.Relational.Query.Internal.ContextType- ) where--import Database.Relational.Query.Internal.ContextType
− src/Database/Relational/Query/Derives.hs
@@ -1,113 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.Derives--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines typed SQLs derived from type informations.-module Database.Relational.Query.Derives (- -- * Query derivation- specifiedKey,-- unique,-- primary', primary,-- -- * Update derivation- updateByConstraintKey,- primaryUpdate,-- updateValuesWithKey,-- -- * Derived objects from table- derivedUniqueRelation- ) where--import Database.Record (PersistableWidth, ToSql (recordToSql))-import Database.Record.ToSql (unsafeUpdateValuesWithIndexes)--import Database.Relational.Query.Table (Table, TableDerivable)-import Database.Relational.Query.Pi.Unsafe (Pi, unsafeExpandIndexes)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable (placeholder, (.=.))-import Database.Relational.Query.ProjectableExtended ((!))-import Database.Relational.Query.Monad.Class (wheres)-import Database.Relational.Query.Monad.BaseType (Relation, relationWidth)-import Database.Relational.Query.Relation- (derivedRelation, relation, relation', query, UniqueRelation, unsafeUnique)-import Database.Relational.Query.Constraint- (Key, Primary, Unique, projectionKey, uniqueKey,- HasConstraintKey(constraintKey))-import qualified Database.Relational.Query.Constraint as Constraint-import Database.Relational.Query.Type (KeyUpdate, typedKeyUpdate)----- | Query restricted with specified key.-specifiedKey :: PersistableWidth p- => Pi a p -- ^ Unique key proof object which record type is 'a' and key type is 'p'.- -> Relation () a -- ^ 'Relation' to add restriction.- -> Relation p a -- ^ Result restricted 'Relation'-specifiedKey key rel = relation' $ do- q <- query rel- (param, ()) <- placeholder (\ph -> wheres $ Projection.wpi (relationWidth rel) q key .=. ph)- return (param, q)---- | Query restricted with specified unique key.-unique :: PersistableWidth p- => Key Unique a p -- ^ Unique key proof object which record type is 'a' and key type is 'p'.- -> Relation () a -- ^ 'Relation' to add restriction.- -> Relation p a -- ^ Result restricted 'Relation'-unique = specifiedKey . projectionKey---- | Query restricted with specified primary key.-primary' :: PersistableWidth p- => Key Primary a p -- ^ Primary key proof object which record type is 'a' and key type is 'p'.- -> Relation () a -- ^ 'Relation' to add restriction.- -> Relation p a -- ^ Result restricted 'Relation'-primary' = specifiedKey . projectionKey---- | Query restricted with inferred primary key.-primary :: HasConstraintKey Primary a p- => Relation () a -- ^ 'Relation' to add restriction.- -> Relation p a -- ^ Result restricted 'Relation'-primary = primary' constraintKey----- | Convert from Haskell type `r` into SQL value `q` list expected by update form like------ /UPDATE <table> SET c0 = ?, c1 = ?, ..., cn = ? WHERE key0 = ? AND key1 = ? AND key2 = ? ... /------ using derived 'RecordToSql' proof object.-updateValuesWithKey :: ToSql q r- => Pi r p- -> r- -> [q]-updateValuesWithKey = unsafeUpdateValuesWithIndexes recordToSql . unsafeExpandIndexes---- | Typed 'KeyUpdate' using specified constraint key.-updateByConstraintKey :: Table r -- ^ 'Table' to update- -> Key c r p -- ^ Key with constraint 'c', record type 'r' and columns type 'p'- -> KeyUpdate p r -- ^ Result typed 'Update'-updateByConstraintKey table' = typedKeyUpdate table' . Constraint.projectionKey---- | Typed 'KeyUpdate' using inferred primary key.-primaryUpdate :: (HasConstraintKey Primary r p)- => Table r -- ^ 'Table' to update- -> KeyUpdate p r -- ^ Result typed 'Update'-primaryUpdate table' = updateByConstraintKey table' (uniqueKey constraintKey)---- | 'UniqueRelation' inferred from table.-derivedUniqueRelation :: TableDerivable r- => Key Unique r k -- ^ Unique key proof object which record type is 'a' and key type is 'p'.- -> Projection c k -- ^ Unique key value to specify.- -> UniqueRelation () c r -- ^ Result restricted 'Relation'-derivedUniqueRelation uk kp = unsafeUnique . relation $ do- r <- query derivedRelation- wheres $ r ! projectionKey uk .=. Projection.unsafeChangeContext kp- return r
− src/Database/Relational/Query/Effect.hs
@@ -1,190 +0,0 @@--- |--- Module : Database.Relational.Query.Effect--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines effect statements--- like update and delete.-module Database.Relational.Query.Effect (- -- * Object to express simple restriction.- Restriction, restriction, restriction',-- -- * Object to express update target columns and restriction.- UpdateTarget, updateTarget, updateTarget',- liftTargetAllColumn, liftTargetAllColumn',- updateTargetAllColumn, updateTargetAllColumn',-- -- * Object to express insert terget.- InsertTarget, insertTarget, insertTarget', piRegister,-- -- * Generate SQL from restriction.- sqlWhereFromRestriction,- sqlFromUpdateTarget,- sqlChunkFromInsertTarget,- sqlFromInsertTarget,- ) where--import Data.Monoid ((<>))--import Language.SQL.Keyword (Keyword(..))-import Database.Record.Persistable (PersistableWidth)--import Database.Relational.Query.Internal.Config (Config (chunksInsertSize), defaultConfig)-import Database.Relational.Query.Internal.SQL (StringSQL, stringSQL, showStringSQL)-import Database.Relational.Query.Internal.BaseSQL (composeSets, composeChunkValuesWithColumns)--import Database.Relational.Query.Pi (Pi, id')-import qualified Database.Relational.Query.Pi.Unsafe as Pi-import Database.Relational.Query.Table (Table, TableDerivable, derivedTable)-import qualified Database.Relational.Query.Table as Table-import Database.Relational.Query.Sub (composeWhere)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable- (PlaceHolders, unitPlaceHolder, unsafeAddPlaceHolders,- pwPlaceholder, placeholder, (><), rightId)-import Database.Relational.Query.Monad.Trans.Assigning (assignings, (<-#))-import Database.Relational.Query.Monad.Restrict (RestrictedStatement)-import qualified Database.Relational.Query.Monad.Restrict as Restrict-import Database.Relational.Query.Monad.Assign (AssignStatement)-import qualified Database.Relational.Query.Monad.Assign as Assign-import Database.Relational.Query.Monad.Register (Register)-import qualified Database.Relational.Query.Monad.Register as Register----- | Restriction type with place-holder parameter 'p' and projection record type 'r'.-newtype Restriction p r = Restriction (RestrictedStatement r (PlaceHolders p))---- | Finalize 'Restrict' monad and generate 'Restriction'.-restriction :: RestrictedStatement r () -> Restriction () r-restriction = Restriction . ((>> return unitPlaceHolder) .)---- | Finalize 'Restrict' monad and generate 'Restriction' with place-holder parameter 'p'-restriction' :: RestrictedStatement r (PlaceHolders p) -> Restriction p r-restriction' = Restriction--runRestriction :: Restriction p r- -> RestrictedStatement r (PlaceHolders p)-runRestriction (Restriction qf) =- fmap fst . unsafeAddPlaceHolders . qf---- | SQL WHERE clause 'StringSQL' string from 'Restriction'.-sqlWhereFromRestriction :: Config -> Table r -> Restriction p r -> StringSQL-sqlWhereFromRestriction config tbl (Restriction q) = composeWhere rs- where (_ph, rs) = Restrict.extract (q $ Projection.unsafeFromTable tbl) config---- | Show where clause.-instance TableDerivable r => Show (Restriction p r) where- show = showStringSQL . sqlWhereFromRestriction defaultConfig derivedTable----- | UpdateTarget type with place-holder parameter 'p' and projection record type 'r'.-newtype UpdateTarget p r = UpdateTarget (AssignStatement r (PlaceHolders p))---- | Finalize 'Target' monad and generate 'UpdateTarget'.-updateTarget :: AssignStatement r ()- -> UpdateTarget () r-updateTarget = UpdateTarget . ((>> return unitPlaceHolder) .)---- | Finalize 'Target' monad and generate 'UpdateTarget' with place-holder parameter 'p'.-updateTarget' :: AssignStatement r (PlaceHolders p)- -> UpdateTarget p r-updateTarget' = UpdateTarget--_runUpdateTarget :: UpdateTarget p r- -> AssignStatement r (PlaceHolders p)-_runUpdateTarget (UpdateTarget qf) =- fmap fst . unsafeAddPlaceHolders . qf--updateAllColumn :: PersistableWidth r- => Restriction p r- -> AssignStatement r (PlaceHolders (r, p))-updateAllColumn rs proj = do- (ph0, ()) <- placeholder (\ph -> id' <-# ph)- ph1 <- assignings $ runRestriction rs proj- return $ ph0 >< ph1---- | Lift 'Restriction' to 'UpdateTarget'. Update target columns are all.-liftTargetAllColumn :: PersistableWidth r- => Restriction () r- -> UpdateTarget r r-liftTargetAllColumn rs = updateTarget' $ \proj -> fmap rightId $ updateAllColumn rs proj---- | Lift 'Restriction' to 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.-liftTargetAllColumn' :: PersistableWidth r- => Restriction p r- -> UpdateTarget (r, p) r-liftTargetAllColumn' rs = updateTarget' $ updateAllColumn rs---- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all.-updateTargetAllColumn :: PersistableWidth r- => RestrictedStatement r ()- -> UpdateTarget r r-updateTargetAllColumn = liftTargetAllColumn . restriction---- | Finalize 'Restrict' monad and generate 'UpdateTarget'. Update target columns are all. With placefolder type 'p'.-updateTargetAllColumn' :: PersistableWidth r- => RestrictedStatement r (PlaceHolders p)- -> UpdateTarget (r, p) r-updateTargetAllColumn' = liftTargetAllColumn' . restriction'----- | SQL SET clause and WHERE clause 'StringSQL' string from 'UpdateTarget'-sqlFromUpdateTarget :: Config -> Table r -> UpdateTarget p r -> StringSQL-sqlFromUpdateTarget config tbl (UpdateTarget q) = composeSets (asR tbl) <> composeWhere rs- where ((_ph, asR), rs) = Assign.extract (q (Projection.unsafeFromTable tbl)) config--instance TableDerivable r => Show (UpdateTarget p r) where- show = showStringSQL . sqlFromUpdateTarget defaultConfig derivedTable----- | InsertTarget type with place-holder parameter 'p' and projection record type 'r'.-newtype InsertTarget p r = InsertTarget (Register r (PlaceHolders p))---- | Finalize 'Register' monad and generate 'InsertTarget'.-insertTarget :: Register r ()- -> InsertTarget () r-insertTarget = InsertTarget . (>> return unitPlaceHolder)---- | Finalize 'Target' monad and generate 'UpdateTarget' with place-holder parameter 'p'.-insertTarget' :: Register r (PlaceHolders p)- -> InsertTarget p r-insertTarget' = InsertTarget---- | parametalized 'Register' monad from 'Pi'-piRegister :: PersistableWidth r- => Pi r r'- -> Register r (PlaceHolders r')-piRegister pi' = do- let (ph', ma) = pwPlaceholder (Pi.width' pi') (\ph -> pi' <-# ph)- () <- ma- return ph'--sqlChunkFromInsertTarget' :: Config- -> Int- -> Table r- -> InsertTarget p r- -> StringSQL-sqlChunkFromInsertTarget' config sz tbl (InsertTarget q) =- INSERT <> INTO <> stringSQL (Table.name tbl) <> composeChunkValuesWithColumns sz (asR tbl)- where- (_ph, asR) = Register.extract q config---- | Make 'StringSQL' string of SQL INSERT record chunk statement from 'InsertTarget'-sqlChunkFromInsertTarget :: Config- -> Table r- -> InsertTarget p r- -> (StringSQL, Int)-sqlChunkFromInsertTarget config tbl it =- (sqlChunkFromInsertTarget' config n tbl it, n)- where- th = chunksInsertSize config- n = (th + w - 1) `quot` w- w = Table.width tbl---- | Make 'StringSQL' string of SQL INSERT statement from 'InsertTarget'-sqlFromInsertTarget :: Config -> Table r -> InsertTarget p r -> StringSQL-sqlFromInsertTarget config = sqlChunkFromInsertTarget' config 1
− src/Database/Relational/Query/Internal/BaseSQL.hs
@@ -1,96 +0,0 @@--- |--- Module : Database.Relational.Query.Internal.BaseSQL--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides base structure of SQL syntax tree.-module Database.Relational.Query.Internal.BaseSQL (- Duplication (..), showsDuplication,- Order (..), Nulls (..), OrderColumn, OrderingTerm, composeOrderBy,- AssignColumn, AssignTerm, Assignment, composeSets,- composeChunkValues, composeChunkValuesWithColumns,- ) where--import Data.Monoid (Monoid (..), (<>))--import Language.SQL.Keyword (Keyword(..), (|*|), (.=.))-import qualified Language.SQL.Keyword as SQL--import Database.Relational.Query.Internal.SQL- (StringSQL, rowConsStringSQL)----- | Result record duplication attribute-data Duplication = All | Distinct deriving Show---- | Compose duplication attribute string.-showsDuplication :: Duplication -> StringSQL-showsDuplication = dup where- dup All = ALL- dup Distinct = DISTINCT----- | Order direction. Ascendant or Descendant.-data Order = Asc | Desc deriving Show---- | Order of null.-data Nulls = NullsFirst | NullsLast deriving Show---- | Type for order-by column-type OrderColumn = StringSQL---- | Type for order-by term-type OrderingTerm = ((Order, Maybe Nulls), OrderColumn)---- | Compose ORDER BY clause from OrderingTerms-composeOrderBy :: [OrderingTerm] -> StringSQL-composeOrderBy = d where- d [] = mempty- d ts@(_:_) = ORDER <> BY <> SQL.fold (|*|) (map showsOt ts)- showsOt ((o, mn), e) = e <> order o <> maybe mempty ((NULLS <>) . nulls) mn- order Asc = ASC- order Desc = DESC- nulls NullsFirst = FIRST- nulls NullsLast = LAST---- | Column SQL String of assignment-type AssignColumn = StringSQL---- | Value SQL String of assignment-type AssignTerm = StringSQL---- | Assignment pair-type Assignment = (AssignColumn, AssignTerm)---- | Compose SET clause from ['Assignment'].-composeSets :: [Assignment] -> StringSQL-composeSets as = assigns where- assignList = foldr (\ (col, term) r ->- (col .=. term) : r)- [] as- assigns | null assignList = error "Update assignment list is null!"- | otherwise = SET <> SQL.fold (|*|) assignList---- | Compose VALUES clause from value expression list.-composeChunkValues :: Int -- ^ record count per chunk- -> [StringSQL] -- ^ value expression list- -> Keyword-composeChunkValues n0 vs =- VALUES <> cvs- where- n | n0 >= 1 = n0- | otherwise = error $ "Invalid record count value: " ++ show n0- cvs = SQL.fold (|*|) . replicate n $ rowConsStringSQL vs---- | Compose VALUES clause from value expression list.-composeChunkValuesWithColumns :: Int -- ^ record count per chunk- -> [Assignment] -- ^- -> StringSQL-composeChunkValuesWithColumns sz as =- rowConsStringSQL cs <> composeChunkValues sz vs- where- (cs, vs) = unzip as
− src/Database/Relational/Query/Internal/Config.hs
@@ -1,74 +0,0 @@--- |--- Module : Database.Relational.Query.Internal.Config--- Copyright : 2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines configuration datatype used in query products.-module Database.Relational.Query.Internal.Config (- NameConfig (..),- ProductUnitSupport (..), SchemaNameMode (..), IdentifierQuotation (..),- Config ( productUnitSupport- , chunksInsertSize- , schemaNameMode- , normalizedTableName- , verboseAsCompilerWarning- , identifierQuotation- , nameConfig),- defaultConfig,- ) where--import Language.Haskell.TH.Name.CamelCase (VarName, varCamelcaseName)-import qualified Database.Record.TH as RecordTH----- | 'NameConfig' type to customize names of expanded templates.-data NameConfig =- NameConfig- { recordConfig :: RecordTH.NameConfig- , relationVarName :: String -> String -> VarName- }--instance Show NameConfig where- show = const "<NameConfig>"---- | Unit of product is supported or not.-data ProductUnitSupport = PUSupported | PUNotSupported deriving Show---- | Schema name qualify mode in SQL string.-data SchemaNameMode- = SchemaQualified -- ^ Schema qualified table name in SQL string- | SchemaNotQualified -- ^ Not qualified table name in SQL string- deriving (Eq, Show)---- | Configuration for quotation of identifiers of SQL.-data IdentifierQuotation = NoQuotation | Quotation Char deriving Show---- | Configuration type.-data Config =- Config- { productUnitSupport :: !ProductUnitSupport- , chunksInsertSize :: !Int- , schemaNameMode :: !SchemaNameMode- , normalizedTableName :: !Bool- , verboseAsCompilerWarning :: !Bool- , identifierQuotation :: !IdentifierQuotation- , nameConfig :: !NameConfig- } deriving Show---- | Default configuration.-defaultConfig :: Config-defaultConfig =- Config { productUnitSupport = PUSupported- , chunksInsertSize = 256- , schemaNameMode = SchemaQualified- , normalizedTableName = True- , verboseAsCompilerWarning = False- , identifierQuotation = NoQuotation- , nameConfig = NameConfig { recordConfig = RecordTH.defaultNameConfig- , relationVarName = const varCamelcaseName- }- }
− src/Database/Relational/Query/Internal/ContextType.hs
@@ -1,39 +0,0 @@-{-# LANGUAGE EmptyDataDecls #-}---- |--- Module : Database.Relational.Query.Internal.ContextType--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines query context tag types.-module Database.Relational.Query.Internal.ContextType (- Flat, Aggregated, Exists, OverWindow,-- Set, SetList, Power,- ) where---- | Type tag for flat (not-aggregated) query-data Flat---- | Type tag for aggregated query-data Aggregated---- | Type tag for exists predicate-data Exists---- | Type tag for window function building-data OverWindow----- | Type tag for normal aggregatings set-data Set---- | Type tag for aggregatings GROUPING SETS-data SetList---- | Type tag for aggregatings power set-data Power
− src/Database/Relational/Query/Internal/GroupingSQL.hs
@@ -1,119 +0,0 @@--- |--- Module : Database.Relational.Query.Internal.GroupingSQL--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides grouping-sets structure of SQL syntax tree.-module Database.Relational.Query.Internal.GroupingSQL (- AggregateColumnRef,- AggregateBitKey (..), AggregateSet (..), AggregateElem (..),-- aggregateColumnRef, aggregateEmpty,- aggregatePowerKey, aggregateGroupingSet,- aggregateRollup, aggregateCube, aggregateSets,-- composeGroupBy, composePartitionBy,-- AggregateKey (..),-- aggregateKeyProjection, aggregateKeyElement, unsafeAggregateKey,- ) where--import Data.Monoid (Monoid (..), (<>))--import Language.SQL.Keyword (Keyword(..), (|*|))-import qualified Language.SQL.Keyword as SQL--import Database.Relational.Query.Internal.SQL (StringSQL)----- | Type for group-by term-type AggregateColumnRef = StringSQL---- | Type for group key.-newtype AggregateBitKey = AggregateBitKey [AggregateColumnRef] deriving Show---- | Type for grouping set-newtype AggregateSet = AggregateSet [AggregateElem] deriving Show---- | Type for group-by tree-data AggregateElem = ColumnRef AggregateColumnRef- | Rollup [AggregateBitKey]- | Cube [AggregateBitKey]- | GroupingSets [AggregateSet]- deriving Show---- | Typeful aggregate element.-newtype AggregateKey a = AggregateKey (a, AggregateElem)---- | Single term aggregation element.-aggregateColumnRef :: AggregateColumnRef -> AggregateElem-aggregateColumnRef = ColumnRef---- | Key of aggregation power set.-aggregatePowerKey :: [AggregateColumnRef] -> AggregateBitKey-aggregatePowerKey = AggregateBitKey---- | Single grouping set.-aggregateGroupingSet :: [AggregateElem] -> AggregateSet-aggregateGroupingSet = AggregateSet---- | Rollup aggregation element.-aggregateRollup :: [AggregateBitKey] -> AggregateElem-aggregateRollup = Rollup---- | Cube aggregation element.-aggregateCube :: [AggregateBitKey] -> AggregateElem-aggregateCube = Cube---- | Grouping sets aggregation.-aggregateSets :: [AggregateSet] -> AggregateElem-aggregateSets = GroupingSets---- | Empty aggregation.-aggregateEmpty :: [AggregateElem]-aggregateEmpty = []--commaed :: [StringSQL] -> StringSQL-commaed = SQL.fold (|*|)--pComma :: (a -> StringSQL) -> [a] -> StringSQL-pComma qshow = SQL.paren . commaed . map qshow--showsAggregateBitKey :: AggregateBitKey -> StringSQL-showsAggregateBitKey (AggregateBitKey ts) = pComma id ts---- | Compose GROUP BY clause from AggregateElem list.-composeGroupBy :: [AggregateElem] -> StringSQL-composeGroupBy = d where- d [] = mempty- d es@(_:_) = GROUP <> BY <> rec es- keyList op ss = op <> pComma showsAggregateBitKey ss- rec = commaed . map showsE- showsGs (AggregateSet s) = SQL.paren $ rec s- showsE (ColumnRef t) = t- showsE (Rollup ss) = keyList ROLLUP ss- showsE (Cube ss) = keyList CUBE ss- showsE (GroupingSets ss) = GROUPING <> SETS <> pComma showsGs ss---- | Compose PARTITION BY clause from AggregateColumnRef list.-composePartitionBy :: [AggregateColumnRef] -> StringSQL-composePartitionBy = d where- d [] = mempty- d ts@(_:_) = PARTITION <> BY <> commaed ts---- | Extract typed projection from 'AggregateKey'.-aggregateKeyProjection :: AggregateKey a -> a-aggregateKeyProjection (AggregateKey (p, _c)) = p---- | Extract untyped term from 'AggregateKey'.-aggregateKeyElement :: AggregateKey a -> AggregateElem-aggregateKeyElement (AggregateKey (_p, c)) = c---- | Unsafely bind typed-projection and untyped-term into 'AggregateKey'.-unsafeAggregateKey :: (a, AggregateElem) -> AggregateKey a-unsafeAggregateKey = AggregateKey
− src/Database/Relational/Query/Internal/Product.hs
@@ -1,53 +0,0 @@--- |--- Module : Database.Relational.Query.Internal.Product--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines product structure to compose SQL join.-module Database.Relational.Query.Internal.Product (- -- * Interfaces to manipulate ProductTree type- growProduct, restrictProduct,- ) where--import Prelude hiding (and, product)-import Control.Applicative (pure)-import Data.Monoid ((<>), mempty)--import Database.Relational.Query.Internal.ContextType (Flat)-import Database.Relational.Query.Internal.Sub- (NodeAttr (..), ProductTree (..), Node (..), Projection, Qualified, SubQuery,- ProductTreeBuilder, ProductBuilder)----- | Push new tree into product right term.-growRight :: Maybe ProductBuilder -- ^ Current tree- -> (NodeAttr, ProductTreeBuilder) -- ^ New tree to push into right- -> ProductBuilder -- ^ Result node-growRight = d where- d Nothing (naR, q) = Node naR q- d (Just l) (naR, q) = Node Just' $ Join l (Node naR q) mempty---- | Push new leaf node into product right term.-growProduct :: Maybe ProductBuilder -- ^ Current tree- -> (NodeAttr, Qualified SubQuery) -- ^ New leaf to push into right- -> ProductBuilder -- ^ Result node-growProduct = match where- match t (na, q) = growRight t (na, Leaf q)---- | Add restriction into top product of product tree.-restrictProduct' :: ProductTreeBuilder -- ^ Product to restrict- -> Projection Flat (Maybe Bool) -- ^ Restriction to add- -> ProductTreeBuilder -- ^ Result product-restrictProduct' = d where- d (Join lp rp rs) rs' = Join lp rp (rs <> pure rs')- d leaf'@(Leaf _) _ = leaf' -- or error on compile---- | Add restriction into top product of product tree node.-restrictProduct :: ProductBuilder -- ^ Target node which has product to restrict- -> Projection Flat (Maybe Bool) -- ^ Restriction to add- -> ProductBuilder -- ^ Result node-restrictProduct (Node a t) e = Node a (restrictProduct' t e)
− src/Database/Relational/Query/Internal/SQL.hs
@@ -1,52 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}---- |--- Module : Database.Relational.Query.Internal.SQL--- Copyright : 2014-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides SQL string wrap interfaces.-module Database.Relational.Query.Internal.SQL (- StringSQL, stringSQL, showStringSQL,-- rowStringSQL, rowPlaceHolderStringSQL,-- rowConsStringSQL, listStringSQL,- ) where--import Language.SQL.Keyword (Keyword, word, wordShow, fold, (|*|), paren)----- | String wrap type for SQL strings.-type StringSQL = Keyword---- | 'StringSQL' from 'String'.-stringSQL :: String -> StringSQL-stringSQL = word---- | 'StringSQL' to 'String'.-showStringSQL :: StringSQL -> String-showStringSQL = wordShow---- | Row String of SQL values.-rowStringSQL :: [StringSQL] -> StringSQL-rowStringSQL = d where- d [] = error "Projection: no columns."- d [c] = c- d cs = paren $ fold (|*|) cs---- | Place holder row String of SQL.-rowPlaceHolderStringSQL :: Int -> StringSQL-rowPlaceHolderStringSQL = rowStringSQL . (`replicate` stringSQL "?")---- | List String of SQL.-rowConsStringSQL :: [StringSQL] -> StringSQL-rowConsStringSQL = paren . fold (|*|)---- | List String of SQL.-listStringSQL :: [StringSQL] -> StringSQL-listStringSQL = paren . fold (|*|)
− src/Database/Relational/Query/Internal/Sub.hs
@@ -1,204 +0,0 @@-{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}---- |--- Module : Database.Relational.Query.Internal.Sub--- Copyright : 2015-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines sub-query structure used in query products.-module Database.Relational.Query.Internal.Sub- ( SubQuery (..)- , SetOp (..), BinOp (..), Qualifier (..)- , Qualified (..), qualifier, unQualify, qualify-- -- * Product tree type- , NodeAttr (..), ProductTree (..)- , Node (..), nodeAttr, nodeTree- , JoinProduct, QueryProductTree- , ProductTreeBuilder, ProductBuilder-- , CaseClause (..), WhenClauses(..)- , caseSearch, case'-- , UntypedProjection, untypedProjectionWidth, ProjectionUnit (..)- , Projection, untypeProjection, typedProjection, projectionWidth- , projectFromColumns, projectFromScalarSubQuery-- -- * Query restriction- , QueryRestriction- ) where--import Prelude hiding (and, product)-import Data.DList (DList)-import Data.Foldable (Foldable)-import Data.Traversable (Traversable)--import Database.Relational.Query.Internal.Config (Config)-import Database.Relational.Query.Internal.ContextType (Flat, Aggregated)-import Database.Relational.Query.Internal.SQL (StringSQL)-import Database.Relational.Query.Internal.BaseSQL (Duplication (..), OrderingTerm)-import Database.Relational.Query.Internal.GroupingSQL (AggregateElem)-import Database.Relational.Query.Internal.UntypedTable (Untyped)----- | Set operators-data SetOp = Union | Except | Intersect deriving Show---- | Set binary operators-newtype BinOp = BinOp (SetOp, Duplication) deriving Show---- | Sub-query type-data SubQuery = Table Untyped- | Flat Config- UntypedProjection Duplication JoinProduct (QueryRestriction Flat)- [OrderingTerm]- | Aggregated Config- UntypedProjection Duplication JoinProduct (QueryRestriction Flat)- [AggregateElem] (QueryRestriction Aggregated) [OrderingTerm]- | Bin BinOp SubQuery SubQuery- deriving Show---- | Qualifier type.-newtype Qualifier = Qualifier Int deriving Show---- | Qualified query.-data Qualified a =- Qualified Qualifier a- deriving (Show, Functor, Foldable, Traversable)---- | Get qualifier-qualifier :: Qualified a -> Qualifier-qualifier (Qualified q _) = q---- | Unqualify.-unQualify :: Qualified a -> a-unQualify (Qualified _ a) = a---- | Add qualifier-qualify :: Qualifier -> a -> Qualified a-qualify = Qualified----- | node attribute for product.-data NodeAttr = Just' | Maybe deriving Show--type QS = Qualified SubQuery--type QueryRestrictionBuilder = DList (Projection Flat (Maybe Bool))---- | Product tree type. Product tree is constructed by left node and right node.-data ProductTree rs- = Leaf QS- | Join !(Node rs) !(Node rs) !rs- deriving (Show, Functor)---- | Product node. node attribute and product tree.-data Node rs = Node !NodeAttr !(ProductTree rs) deriving (Show, Functor)---- | Get node attribute.-nodeAttr :: Node rs -> NodeAttr-nodeAttr (Node a _) = a where---- | Get tree from node.-nodeTree :: Node rs -> ProductTree rs-nodeTree (Node _ t) = t---- | Product tree with join restriction.-type QueryProductTree = ProductTree (QueryRestriction Flat)---- | Product tree with join restriction builder.-type ProductTreeBuilder = ProductTree QueryRestrictionBuilder---- | Product noe with join restriction builder.-type ProductBuilder = Node QueryRestrictionBuilder---- | Type for join product of query.-type JoinProduct = Maybe QueryProductTree---- | when clauses-data WhenClauses =- WhenClauses [(UntypedProjection, UntypedProjection)] UntypedProjection- deriving Show---- | case clause-data CaseClause- = CaseSearch WhenClauses- | CaseSimple UntypedProjection WhenClauses- deriving Show---- | Projection structure unit with single column width-data ProjectionUnit- = RawColumn StringSQL -- ^ used in immediate value or unsafe operations- | SubQueryRef (Qualified Int) -- ^ normalized sub-query reference T<n> with Int index- | Scalar SubQuery -- ^ scalar sub-query- | Case CaseClause Int -- ^ <n>th column of case clause- deriving Show---- | Untyped projection. Forgot record type.-type UntypedProjection = [ProjectionUnit]---- | Width of 'UntypedProjection'.-untypedProjectionWidth :: UntypedProjection -> Int-untypedProjectionWidth = length---- | Phantom typed projection. Projected into Haskell record type 't'.-newtype Projection c t =- Projection- { untypeProjection :: UntypedProjection {- ^ Discard projection value type -} } deriving Show---- | Unsafely type projection value.-typedProjection :: UntypedProjection -> Projection c t-typedProjection = Projection---- | Width of 'Projection'.-projectionWidth :: Projection c r -> Int-projectionWidth = length . untypeProjection---- | Unsafely generate 'Projection' from SQL string list.-projectFromColumns :: [StringSQL] -- ^ SQL string list specifies columns- -> Projection c r -- ^ Result 'Projection'-projectFromColumns = typedProjection . map RawColumn---- | Unsafely generate 'Projection' from scalar sub-query.-projectFromScalarSubQuery :: SubQuery -> Projection c t-projectFromScalarSubQuery = typedProjection . (:[]) . Scalar--whenClauses :: String -- ^ Error tag- -> [(Projection c a, Projection c b)] -- ^ Each when clauses- -> Projection c b -- ^ Else result projection- -> WhenClauses -- ^ Result clause-whenClauses eTag ws0 e = d ws0- where- d [] = error $ eTag ++ ": Empty when clauses!"- d ws@(_:_) =- WhenClauses [ (untypeProjection p, untypeProjection r) | (p, r) <- ws ]- $ untypeProjection e---- | Search case operator correnponding SQL search /CASE/.--- Like, /CASE WHEN p0 THEN a WHEN p1 THEN b ... ELSE c END/-caseSearch :: [(Projection c (Maybe Bool), Projection c a)] -- ^ Each when clauses- -> Projection c a -- ^ Else result projection- -> Projection c a -- ^ Result projection-caseSearch ws e =- typedProjection [ Case c i | i <- [0 .. projectionWidth e - 1] ]- where- c = CaseSearch $ whenClauses "caseSearch" ws e---- | Simple case operator correnponding SQL simple /CASE/.--- Like, /CASE x WHEN v THEN a WHEN w THEN b ... ELSE c END/-case' :: Projection c a -- ^ Projection value to match- -> [(Projection c a, Projection c b)] -- ^ Each when clauses- -> Projection c b -- ^ Else result projection- -> Projection c b -- ^ Result projection-case' v ws e =- typedProjection [ Case c i | i <- [0 .. projectionWidth e - 1] ]- where- c = CaseSimple (untypeProjection v) $ whenClauses "case'" ws e----- | Type for restriction of query.-type QueryRestriction c = [Projection c (Maybe Bool)]
− src/Database/Relational/Query/Internal/UntypedTable.hs
@@ -1,44 +0,0 @@--- |--- Module : Database.Relational.Query.Internal.UntypedTable--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines no-phantom table type which has table metadatas.-module Database.Relational.Query.Internal.UntypedTable (- Untyped (Untyped), name', width', columns', (!),- ) where--import Data.Array (Array, elems)-import qualified Data.Array as Array--import Database.Relational.Query.Internal.SQL (StringSQL)----- | Untyped typed table type-data Untyped = Untyped String Int (Array Int StringSQL) deriving Show---- | Name string of table in SQL-name' :: Untyped -> String-name' (Untyped n _ _) = n---- | Width of table-width' :: Untyped -> Int-width' (Untyped _ w _) = w---- | Column name strings in SQL-columnArray :: Untyped -> Array Int StringSQL-columnArray (Untyped _ _ c) = c---- | Column name strings in SQL-columns' :: Untyped -> [StringSQL]-columns' = elems . columnArray---- | Column name string in SQL specified by index-(!) :: Untyped- -> Int -- ^ Column index- -> StringSQL -- ^ Column name String in SQL-t ! i = columnArray t Array.! i
− src/Database/Relational/Query/Monad/Aggregate.hs
@@ -1,103 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE TypeSynonymInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Aggregate--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about aggregated query type.-module Database.Relational.Query.Monad.Aggregate (- -- * Aggregated Query- QueryAggregate,- AggregatedQuery,-- toSQL,-- toSubQuery,-- Window, over- ) where--import Data.Functor.Identity (Identity (runIdentity))-import Data.Monoid ((<>))--import Language.SQL.Keyword (Keyword(..))-import qualified Language.SQL.Keyword as SQL--import Database.Relational.Query.Internal.BaseSQL (Duplication, OrderingTerm, composeOrderBy)-import Database.Relational.Query.Internal.GroupingSQL (AggregateColumnRef, AggregateElem, composePartitionBy)--import Database.Relational.Query.Context (Flat, Aggregated, OverWindow)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Sub (SubQuery, QueryRestriction, JoinProduct, aggregatedSubQuery)-import qualified Database.Relational.Query.Sub as SubQuery-import Database.Relational.Query.Projectable (PlaceHolders, SqlProjectable)-import Database.Relational.Query.Monad.Class (MonadRestrict(..))-import Database.Relational.Query.Monad.Trans.Restricting- (Restrictings, restrictings, extractRestrict)-import Database.Relational.Query.Monad.Trans.Aggregating- (extractAggregateTerms, AggregatingSetT, PartitioningSet)-import Database.Relational.Query.Monad.Trans.Ordering- (Orderings, extractOrderingTerms)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, askConfig)-import Database.Relational.Query.Monad.Type (QueryCore, extractCore, OrderedQuery)----- | Aggregated query monad type.-type QueryAggregate = Orderings Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore))---- | Aggregated query type. 'AggregatedQuery' p r == 'QueryAggregate' ('PlaceHolders' p, 'Projection' 'Aggregated' r).-type AggregatedQuery p r = OrderedQuery Aggregated (Restrictings Aggregated (AggregatingSetT QueryCore)) p r---- | Partition monad type for partition-by clause.-type Window c = Orderings c (PartitioningSet c)---- | Restricted 'MonadRestrict' instance.-instance MonadRestrict Flat q => MonadRestrict Flat (Restrictings Aggregated q) where- restrict = restrictings . restrict--extract :: AggregatedQuery p r- -> ConfigureQuery (((((((PlaceHolders p, Projection Aggregated r), [OrderingTerm]),- QueryRestriction Aggregated),- [AggregateElem]),- QueryRestriction Flat),- JoinProduct), Duplication)-extract = extractCore . extractAggregateTerms . extractRestrict . extractOrderingTerms---- | Run 'AggregatedQuery' to get SQL with 'ConfigureQuery' computation.-toSQL :: AggregatedQuery p r -- ^ 'AggregatedQuery' to run- -> ConfigureQuery String -- ^ Result SQL string with 'ConfigureQuery' computation-toSQL = fmap SubQuery.toSQL . toSubQuery---- | Run 'AggregatedQuery' to get 'SubQuery' with 'ConfigureQuery' computation.-toSubQuery :: AggregatedQuery p r -- ^ 'AggregatedQuery' to run- -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'ConfigureQuery' computation-toSubQuery q = do- (((((((_ph, pj), ot), grs), ag), rs), pd), da) <- extract q- c <- askConfig- return $ aggregatedSubQuery c (Projection.untype pj) da pd rs ag grs ot--extractWindow :: Window c a -> ((a, [OrderingTerm]), [AggregateColumnRef])-extractWindow = runIdentity . extractAggregateTerms . extractOrderingTerms---- | Operator to make window function result projection using built 'Window' monad.-over :: SqlProjectable (Projection c)- => Projection OverWindow a- -> Window c ()- -> Projection c a-wp `over` win =- Projection.unsafeFromSqlTerms- [ c <> OVER <> SQL.paren (composePartitionBy pt <> composeOrderBy ot)- | c <- Projection.columns wp- ] where (((), ot), pt) = extractWindow win--infix 8 `over`
− src/Database/Relational/Query/Monad/Assign.hs
@@ -1,49 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Assign--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about restrict context with assignment monad type.-module Database.Relational.Query.Monad.Assign (- -- * Monad to restrict target records with assignment.- Assign, AssignStatement,- -- updateStatement,- extract,- ) where--import Database.Relational.Query.Internal.BaseSQL (Assignment)-import Database.Relational.Query.Internal.Config (Config)--import Database.Relational.Query.Sub (QueryRestriction)-import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Table (Table)-import Database.Relational.Query.Projection (Projection)-import Database.Relational.Query.Monad.Restrict (Restrict)-import qualified Database.Relational.Query.Monad.Restrict as Restrict-import Database.Relational.Query.Monad.Trans.Assigning (Assignings, extractAssignments)----- | Target update monad type used from update statement and merge statement.-type Assign r = Assignings r Restrict---- | AssignStatement type synonym.--- Specifying assignments and restrictions like update statement.--- Projection record type must be--- the same as 'Target' type parameter 'r'.-type AssignStatement r a = Projection Flat r -> Assign r a---- -- | 'return' of 'Update'--- updateStatement :: a -> Assignings r (Restrictings Identity) a--- updateStatement = assignings . restrictings . Identity---- | Run 'Assign'.-extract :: Assign r a -> Config -> ((a, Table r -> [Assignment]), QueryRestriction Flat)-extract = Restrict.extract . extractAssignments
− src/Database/Relational/Query/Monad/BaseType.hs
@@ -1,95 +0,0 @@--- |--- Module : Database.Relational.Query.Monad.BaseType--- Copyright : 2015-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines base monad type to build queries.-module Database.Relational.Query.Monad.BaseType- ( -- * Base monad type to build queries- ConfigureQuery, configureQuery,- qualifyQuery, askConfig,-- -- * Relation type- Relation, unsafeTypeRelation, untypeRelation, relationWidth,-- dump,- sqlFromRelationWith, sqlFromRelation,-- rightPh, leftPh,- ) where--import Data.Functor.Identity (Identity, runIdentity)-import Control.Applicative ((<$>))--import Database.Record.Persistable (PersistableRecordWidth, unsafePersistableRecordWidth)--import Database.Relational.Query.Internal.Config (Config, defaultConfig)-import Database.Relational.Query.Internal.SQL (StringSQL, showStringSQL)--import Database.Relational.Query.Sub (Qualified, SubQuery, showSQL, width)-import qualified Database.Relational.Query.Monad.Trans.Qualify as Qualify-import Database.Relational.Query.Monad.Trans.Qualify (Qualify, qualify, evalQualifyPrime)-import Database.Relational.Query.Monad.Trans.Config (QueryConfig, runQueryConfig, askQueryConfig)---- | Thin monad type for untyped structure.-type ConfigureQuery = Qualify (QueryConfig Identity)---- | Run 'ConfigureQuery' monad with initial state to get only result.-configureQuery :: ConfigureQuery q -> Config -> q-configureQuery cq c = runIdentity $ runQueryConfig (evalQualifyPrime cq) c---- | Get qualifyed table form query.-qualifyQuery :: a -> ConfigureQuery (Qualified a)-qualifyQuery = Qualify.qualifyQuery---- | Read configuration.-askConfig :: ConfigureQuery Config-askConfig = qualify askQueryConfig----- | Relation type with place-holder parameter 'p' and query result type 'r'.-newtype Relation p r = SubQuery (ConfigureQuery SubQuery)---- | Unsafely type qualified subquery into record typed relation type.-unsafeTypeRelation :: ConfigureQuery SubQuery -> Relation p r-unsafeTypeRelation = SubQuery---- | Sub-query Qualify monad from relation.-untypeRelation :: Relation p r -> ConfigureQuery SubQuery-untypeRelation (SubQuery qsub) = qsub---- | 'PersistableRecordWidth' of 'Relation' type.-relationWidth :: Relation p r -> PersistableRecordWidth r-relationWidth rel =- unsafePersistableRecordWidth . width $ configureQuery (untypeRelation rel) defaultConfig- --- Assume that width is independent from Config structure--unsafeCastPlaceHolder :: Relation a r -> Relation b r-unsafeCastPlaceHolder (SubQuery qsub) = SubQuery qsub---- | Simplify placeholder type applying left identity element.-rightPh :: Relation ((), p) r -> Relation p r-rightPh = unsafeCastPlaceHolder---- | Simplify placeholder type applying right identity element.-leftPh :: Relation (p, ()) r -> Relation p r-leftPh = unsafeCastPlaceHolder---- | Generate SQL string from 'Relation' with configuration.-sqlFromRelationWith :: Relation p r -> Config -> StringSQL-sqlFromRelationWith = configureQuery . (showSQL <$>) . untypeRelation---- | SQL string from 'Relation'.-sqlFromRelation :: Relation p r -> StringSQL-sqlFromRelation = (`sqlFromRelationWith` defaultConfig)---- | Dump internal structure tree.-dump :: Relation p r -> String-dump = show . (`configureQuery` defaultConfig) . untypeRelation--instance Show (Relation p r) where- show = showStringSQL . sqlFromRelation
− src/Database/Relational/Query/Monad/Class.hs
@@ -1,95 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Class--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines query building interface classes.-module Database.Relational.Query.Monad.Class- ( -- * Query interface classes- MonadQualify (..), MonadRestrict (..),- MonadQuery (..), MonadAggregate (..), MonadPartition (..),-- all', distinct,- on, wheres, having,- ) where--import Database.Relational.Query.Internal.BaseSQL (Duplication (..))-import Database.Relational.Query.Internal.GroupingSQL (AggregateKey)--import Database.Relational.Query.Context (Flat, Aggregated)-import Database.Relational.Query.Projection (Projection)-import Database.Relational.Query.Projectable (PlaceHolders)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, Relation)----- | Restrict context interface-class (Functor m, Monad m) => MonadRestrict c m where- -- | Add restriction to this context.- restrict :: Projection c (Maybe Bool) -- ^ 'Projection' which represent restriction- -> m () -- ^ Restricted query context---- | Query building interface.-class (Functor m, Monad m, MonadQualify ConfigureQuery m) => MonadQuery m where- -- | Specify duplication.- setDuplication :: Duplication -> m ()- -- | Add restriction to last join.- restrictJoin :: Projection Flat (Maybe Bool) -- ^ 'Projection' which represent restriction- -> m () -- ^ Restricted query context- {- Haddock BUG? -}- -- | Join sub-query with place-holder parameter 'p'. query result is not 'Maybe'.- query' :: Relation p r- -> m (PlaceHolders p, Projection Flat r)- -- | Join sub-query with place-holder parameter 'p'. Query result is 'Maybe'.- queryMaybe' :: Relation p r- -> m (PlaceHolders p, Projection Flat (Maybe r))---- | Lift interface from base qualify monad.-class (Functor q, Monad q, Functor m, Monad m) => MonadQualify q m where- -- | Lift from qualify monad 'q' into 'MonadQuery' m.- -- Qualify monad qualifies table form 'SubQuery'.- liftQualify :: q a -> m a--instance (Functor q, Monad q) => MonadQualify q q where- liftQualify = id---- | Aggregated query building interface extends 'MonadQuery'.-class MonadQuery m => MonadAggregate m where- -- | Add /GROUP BY/ term into context and get aggregated projection.- groupBy :: Projection Flat r -- ^ Projection to add into group by- -> m (Projection Aggregated r) -- ^ Result context and aggregated projection- -- | Add /GROUP BY/ term into context and get aggregated projection. Non-traditional group-by version.- groupBy' :: AggregateKey (Projection Aggregated r) -- ^ Key to aggretate for non-traditional group-by interface- -> m (Projection Aggregated r) -- ^ Result context and aggregated projection---- | Window specification building interface.-class Monad m => MonadPartition c m where- -- | Add /PARTITION BY/ term into context.- partitionBy :: Projection c r -> m ()---- | Specify ALL attribute to query context.-all' :: MonadQuery m => m ()-all' = setDuplication All---- | Specify DISTINCT attribute to query context.-distinct :: MonadQuery m => m ()-distinct = setDuplication Distinct---- | Add restriction to last join. Projection type version.-on :: MonadQuery m => Projection Flat (Maybe Bool) -> m ()-on = restrictJoin---- | Add restriction to this not aggregated query.-wheres :: MonadRestrict Flat m => Projection Flat (Maybe Bool) -> m ()-wheres = restrict---- | Add restriction to this aggregated query. Aggregated Projection type version.-having :: MonadRestrict Aggregated m => Projection Aggregated (Maybe Bool) -> m ()-having = restrict
− src/Database/Relational/Query/Monad/Register.hs
@@ -1,31 +0,0 @@--- |--- Module : Database.Relational.Query.Monad.Register--- Copyright : 2015-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about assignment monad type to build insert statement.-module Database.Relational.Query.Monad.Register (- -- * Monad to register target records.- Register,-- extract,- ) where--import Database.Relational.Query.Internal.BaseSQL (Assignment)-import Database.Relational.Query.Internal.Config (Config)--import Database.Relational.Query.Table (Table)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, configureQuery)-import Database.Relational.Query.Monad.Trans.Assigning (Assignings, extractAssignments)----- | Target register monad type used from insert statement.-type Register r = Assignings r ConfigureQuery---- | Run 'InsertStatement'.-extract :: Assignings r ConfigureQuery a -> Config -> (a, Table r -> [Assignment])-extract = configureQuery . extractAssignments
− src/Database/Relational/Query/Monad/Restrict.hs
@@ -1,47 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Restrict--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about simple restrict context monad type.-module Database.Relational.Query.Monad.Restrict (- -- * Monad to restrict target records.- Restrict, RestrictedStatement,-- -- restricted,- extract- ) where--import Database.Relational.Query.Internal.Config (Config)--import Database.Relational.Query.Sub (QueryRestriction)-import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Projection (Projection)-import Database.Relational.Query.Monad.Trans.Restricting- (Restrictings, extractRestrict)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, configureQuery)----- | Restrict only monad type used from update statement and delete statement.-type Restrict = Restrictings Flat ConfigureQuery---- | RestrictedStatement type synonym.--- Projection record type 'r' must be--- the same as 'Restrictings' type parameter 'r'.-type RestrictedStatement r a = Projection Flat r -> Restrict a---- -- | 'return' of 'Restrict'--- restricted :: a -> Restrict a--- restricted = restrict . Identity---- | Run 'Restrict' to get 'QueryRestriction'.-extract :: Restrict a -> Config -> (a, QueryRestriction Flat)-extract = configureQuery . extractRestrict
− src/Database/Relational/Query/Monad/Simple.hs
@@ -1,69 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Simple--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about simple (not-aggregated) query type.-module Database.Relational.Query.Monad.Simple (- -- * Simple query- QuerySimple, SimpleQuery,-- simple,-- toSQL,- toSubQuery,- ) where--import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection--import Database.Relational.Query.Internal.BaseSQL (Duplication, OrderingTerm)--import Database.Relational.Query.Monad.Trans.Join (join')-import Database.Relational.Query.Monad.Trans.Restricting (restrictings)-import Database.Relational.Query.Monad.Trans.Ordering- (Orderings, orderings, extractOrderingTerms)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, askConfig)-import Database.Relational.Query.Monad.Type (QueryCore, extractCore, OrderedQuery)-import Database.Relational.Query.Projectable (PlaceHolders)--import Database.Relational.Query.Sub (SubQuery, QueryRestriction, JoinProduct, flatSubQuery)-import qualified Database.Relational.Query.Sub as SubQuery----- | Simple (not-aggregated) query monad type.-type QuerySimple = Orderings Flat QueryCore---- | Simple (not-aggregated) query type. 'SimpleQuery'' p r == 'QuerySimple' ('PlaceHolders' p, 'Projection' r).-type SimpleQuery p r = OrderedQuery Flat QueryCore p r---- | Lift from qualified table forms into 'QuerySimple'.-simple :: ConfigureQuery a -> QuerySimple a-simple = orderings . restrictings . join'--extract :: SimpleQuery p r- -> ConfigureQuery (((((PlaceHolders p, Projection Flat r), [OrderingTerm]), QueryRestriction Flat),- JoinProduct), Duplication)-extract = extractCore . extractOrderingTerms---- | Run 'SimpleQuery' to get SQL string with 'Qualify' computation.-toSQL :: SimpleQuery p r -- ^ 'SimpleQuery' to run- -> ConfigureQuery String -- ^ Result SQL string with 'Qualify' computation-toSQL = fmap SubQuery.toSQL . toSubQuery---- | Run 'SimpleQuery' to get 'SubQuery' with 'Qualify' computation.-toSubQuery :: SimpleQuery p r -- ^ 'SimpleQuery'' to run- -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'Qualify' computation-toSubQuery q = do- (((((_ph, pj), ot), rs), pd), da) <- extract q- c <- askConfig- return $ flatSubQuery c (Projection.untype pj) da pd rs ot
− src/Database/Relational/Query/Monad/Trans/Aggregating.hs
@@ -1,169 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Aggregating--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which lift--- from 'MonadQuery' into Aggregated query.-module Database.Relational.Query.Monad.Trans.Aggregating- ( -- * Transformer into aggregated query- Aggregatings, aggregatings,-- AggregatingSetT, AggregatingSetListT, AggregatingPowerSetT, PartitioningSetT,-- -- * Result- extractAggregateTerms,-- -- * Grouping sets support- AggregatingSet, AggregatingPowerSet, AggregatingSetList, PartitioningSet,- key, key', set,- bkey, rollup, cube, groupingSets,- ) where--import Control.Monad.Trans.Class (MonadTrans (lift))-import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)-import Control.Applicative (Applicative, pure, (<$>))-import Control.Arrow (second)-import Data.DList (DList, toList)--import Data.Functor.Identity (Identity (runIdentity))--import Database.Relational.Query.Internal.GroupingSQL- (AggregateColumnRef, AggregateElem, aggregateColumnRef, AggregateSet, aggregateGroupingSet,- AggregateBitKey, aggregatePowerKey, aggregateRollup, aggregateCube, aggregateSets,- AggregateKey, aggregateKeyProjection, aggregateKeyElement, unsafeAggregateKey)--import Database.Relational.Query.Context (Flat, Aggregated, Set, Power, SetList)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Monad.Class- (MonadQualify (..), MonadRestrict(..), MonadQuery(..), MonadAggregate(..), MonadPartition(..))----- | Type to accumulate aggregating context.--- Type 'ac' is aggregating-context type like aggregating key set building,--- aggregating key sets set building and partition key set building.--- Type 'at' is aggregating term type.-newtype Aggregatings ac at m a =- Aggregatings (WriterT (DList at) m a)- deriving (MonadTrans, Monad, Functor, Applicative)---- | Lift to 'Aggregatings'.-aggregatings :: Monad m => m a -> Aggregatings ac at m a-aggregatings = lift---- | Context type building one grouping set.-type AggregatingSetT = Aggregatings Set AggregateElem---- | Context type building grouping sets list.-type AggregatingSetListT = Aggregatings SetList AggregateSet---- | Context type building power group set.-type AggregatingPowerSetT = Aggregatings Power AggregateBitKey---- | Context type building partition keys set.-type PartitioningSetT c = Aggregatings c AggregateColumnRef---- | Aggregated 'MonadRestrict'.-instance MonadRestrict c m => MonadRestrict c (AggregatingSetT m) where- restrict = aggregatings . restrict---- | Aggregated 'MonadQualify'.-instance MonadQualify q m => MonadQualify q (AggregatingSetT m) where- liftQualify = aggregatings . liftQualify---- | Aggregated 'MonadQuery'.-instance MonadQuery m => MonadQuery (AggregatingSetT m) where- setDuplication = aggregatings . setDuplication- restrictJoin = aggregatings . restrictJoin- query' = aggregatings . query'- queryMaybe' = aggregatings . queryMaybe'--unsafeAggregateWithTerm :: Monad m => at -> Aggregatings ac at m ()-unsafeAggregateWithTerm = Aggregatings . tell . pure--aggregateKey :: Monad m => AggregateKey a -> Aggregatings ac AggregateElem m a-aggregateKey k = do- unsafeAggregateWithTerm $ aggregateKeyElement k- return $ aggregateKeyProjection k---- | Aggregated query instance.-instance MonadQuery m => MonadAggregate (AggregatingSetT m) where- groupBy p = do- mapM_ unsafeAggregateWithTerm [ aggregateColumnRef col | col <- Projection.columns p]- return $ Projection.unsafeToAggregated p- groupBy' = aggregateKey---- | Partition clause instance-instance Monad m => MonadPartition c (PartitioningSetT c m) where- partitionBy = mapM_ unsafeAggregateWithTerm . Projection.columns---- | Run 'Aggregatings' to get terms list.-extractAggregateTerms :: (Monad m, Functor m) => Aggregatings ac at m a -> m (a, [at])-extractAggregateTerms (Aggregatings ac) = second toList <$> runWriterT ac--extractTermList :: Aggregatings ac at Identity a -> (a, [at])-extractTermList = runIdentity . extractAggregateTerms---- | Context monad type to build single grouping set.-type AggregatingSet = AggregatingSetT Identity---- | Context monad type to build grouping power set.-type AggregatingPowerSet = AggregatingPowerSetT Identity---- | Context monad type to build grouping set list.-type AggregatingSetList = AggregatingSetListT Identity---- | Context monad type to build partition keys set.-type PartitioningSet c = PartitioningSetT c Identity---- | Specify key of single grouping set from Projection.-key :: Projection Flat r- -> AggregatingSet (Projection Aggregated (Maybe r))-key p = do- mapM_ unsafeAggregateWithTerm [ aggregateColumnRef col | col <- Projection.columns p]- return . Projection.just $ Projection.unsafeToAggregated p---- | Specify key of single grouping set.-key' :: AggregateKey a- -> AggregatingSet a-key' = aggregateKey---- | Finalize and specify single grouping set.-set :: AggregatingSet a- -> AggregatingSetList a-set s = do- let (p, c) = second aggregateGroupingSet . extractTermList $ s- unsafeAggregateWithTerm c- return p---- | Specify key of rollup and cube power set.-bkey :: Projection Flat r- -> AggregatingPowerSet (Projection Aggregated (Maybe r))-bkey p = do- unsafeAggregateWithTerm . aggregatePowerKey $ Projection.columns p- return . Projection.just $ Projection.unsafeToAggregated p--finalizePower :: ([AggregateBitKey] -> AggregateElem)- -> AggregatingPowerSet a -> AggregateKey a-finalizePower finalize pow = unsafeAggregateKey . second finalize . extractTermList $ pow---- | Finalize grouping power set as rollup power set.-rollup :: AggregatingPowerSet a -> AggregateKey a-rollup = finalizePower aggregateRollup---- | Finalize grouping power set as cube power set.-cube :: AggregatingPowerSet a -> AggregateKey a-cube = finalizePower aggregateCube---- | Finalize grouping set list.-groupingSets :: AggregatingSetList a -> AggregateKey a-groupingSets = unsafeAggregateKey . second aggregateSets . extractTermList
− src/Database/Relational/Query/Monad/Trans/Assigning.hs
@@ -1,85 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Assigning--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which lift--- from context into context with assigning.-module Database.Relational.Query.Monad.Trans.Assigning (- -- * Transformer into context with assignments- Assignings, assignings,-- -- * API of context with assignments- assignTo, (<-#), AssignTarget,-- -- * Result SQL set clause- extractAssignments- ) where--import Control.Monad.Trans.Class (MonadTrans (lift))-import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)-import Control.Applicative (Applicative, pure, (<$>))-import Control.Arrow (second)-import Data.Monoid (mconcat)-import Data.DList (DList, toList)--import Database.Relational.Query.Internal.BaseSQL (Assignment)--import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Pi (Pi)-import Database.Relational.Query.Table (Table, recordWidth)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Monad.Class (MonadQualify (..), MonadRestrict(..))----- | Type to accumulate assigning context.--- Type 'r' is table record type.-newtype Assignings r m a =- Assignings (WriterT (Table r -> DList Assignment) m a)- deriving (MonadTrans, Monad, Functor, Applicative)---- | Lift to 'Assignings'-assignings :: Monad m => m a -> Assignings r m a-assignings = lift---- | 'MonadRestrict' with assigning.-instance MonadRestrict c m => MonadRestrict c (Assignings r m) where- restrict = assignings . restrict---- | 'MonadQualify' with assigning.-instance MonadQualify q m => MonadQualify q (Assignings r m) where- liftQualify = assignings . liftQualify---- | Target of assignment.-type AssignTarget r v = Pi r v--targetProjection :: AssignTarget r v -> Table r -> Projection Flat v-targetProjection pi' tbl = Projection.wpi (recordWidth tbl) (Projection.unsafeFromTable tbl) pi'---- | Add an assignment.-assignTo :: Monad m => Projection Flat v -> AssignTarget r v -> Assignings r m ()-assignTo vp target = Assignings . tell- $ \t -> mconcat $ zipWith (curry pure) (leftsR t) rights where- leftsR = Projection.columns . targetProjection target- rights = Projection.columns vp---- | Add and assginment.-(<-#) :: Monad m => AssignTarget r v -> Projection Flat v -> Assignings r m ()-(<-#) = flip assignTo--infix 4 <-#---- | Run 'Assignings' to get 'Assignments'-extractAssignments :: (Monad m, Functor m)- => Assignings r m a- -> m (a, Table r -> [Assignment])-extractAssignments (Assignings ac) = second (toList .) <$> runWriterT ac
− src/Database/Relational/Query/Monad/Trans/Config.hs
@@ -1,41 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Config--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which requires query generate configuration.-module Database.Relational.Query.Monad.Trans.Config (- -- * Transformer into query with configuration- QueryConfig, queryConfig,- runQueryConfig, askQueryConfig- ) where--import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.Reader (ReaderT, runReaderT, ask)-import Control.Applicative (Applicative)--import Database.Relational.Query.Internal.Config (Config)----- | 'ReaderT' type to require query generate configuration.-newtype QueryConfig m a =- QueryConfig (ReaderT Config m a)- deriving (Monad, Functor, Applicative)---- | Run 'QueryConfig' to expand with configuration-runQueryConfig :: QueryConfig m a -> Config -> m a-runQueryConfig (QueryConfig r) = runReaderT r---- | Lift to 'QueryConfig'.-queryConfig :: Monad m => m a -> QueryConfig m a-queryConfig = QueryConfig . lift---- | Read configuration.-askQueryConfig :: Monad m => QueryConfig m Config-askQueryConfig = QueryConfig ask
− src/Database/Relational/Query/Monad/Trans/Join.hs
@@ -1,106 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Join--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which lift to basic 'MonadQuery'.-module Database.Relational.Query.Monad.Trans.Join- ( -- * Transformer into join query- QueryJoin, join',-- -- * Result- extractProduct,-- -- * Unsafe API- unsafeSubQueryWithAttr,- ) where--import Prelude hiding (product)-import Control.Monad.Trans.Class (MonadTrans (lift))-import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)-import Control.Monad.Trans.State (modify, StateT, runStateT)-import Control.Applicative (Applicative, (<$>))-import Control.Arrow (second, (***))-import Data.Maybe (fromMaybe)-import Data.Monoid (Last (Last, getLast))--import Database.Relational.Query.Internal.BaseSQL (Duplication (All))-import Database.Relational.Query.Internal.Product (restrictProduct, growProduct)--import Database.Relational.Query.Sub (NodeAttr (Just', Maybe), SubQuery, Qualified, JoinProduct, Projection)-import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Monad.Trans.JoinState- (JoinContext, primeJoinContext, updateProduct, joinProduct)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable (PlaceHolders, unsafeAddPlaceHolders)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, qualifyQuery, Relation, untypeRelation)-import Database.Relational.Query.Monad.Class (MonadQualify (..), MonadQuery (..))----- | 'StateT' type to accumulate join product context.-newtype QueryJoin m a =- QueryJoin (StateT JoinContext (WriterT (Last Duplication) m) a)- deriving (Monad, Functor, Applicative)--instance MonadTrans QueryJoin where- lift = QueryJoin . lift . lift---- | Lift to 'QueryJoin'-join' :: Monad m => m a -> QueryJoin m a-join' = lift---- | Unsafely update join product context.-updateContext :: Monad m => (JoinContext -> JoinContext) -> QueryJoin m ()-updateContext = QueryJoin . modify---- | Add last join product restriction.-updateJoinRestriction :: Monad m => Projection Flat (Maybe Bool) -> QueryJoin m ()-updateJoinRestriction e = updateContext (updateProduct d) where- d Nothing = error "on: Product is empty! Restrict target product is not found!"- d (Just pt) = restrictProduct pt e--instance MonadQualify q m => MonadQualify q (QueryJoin m) where- liftQualify = join' . liftQualify---- | Joinable query instance.-instance MonadQuery (QueryJoin ConfigureQuery) where- setDuplication = QueryJoin . lift . tell . Last . Just- restrictJoin = updateJoinRestriction- query' = queryWithAttr Just'- queryMaybe' pr = do- (ph, pj) <- queryWithAttr Maybe pr- return (ph, Projection.just pj)---- | Unsafely join sub-query with this query.-unsafeSubQueryWithAttr :: Monad q- => NodeAttr -- ^ Attribute maybe or just- -> Qualified SubQuery -- ^ 'SubQuery' to join- -> QueryJoin q (Projection c r) -- ^ Result joined context and 'SubQuery' result projection.-unsafeSubQueryWithAttr attr qsub = do- updateContext (updateProduct (`growProduct` (attr, qsub)))- return $ Projection.unsafeFromQualifiedSubQuery qsub---- | Basic monadic join operation using 'MonadQuery'.-queryWithAttr :: NodeAttr- -> Relation p r- -> QueryJoin ConfigureQuery (PlaceHolders p, Projection c r)-queryWithAttr attr = unsafeAddPlaceHolders . run where- run rel = do- q <- liftQualify $ do- sq <- untypeRelation rel- qualifyQuery sq- unsafeSubQueryWithAttr attr q---- | Run 'QueryJoin' to get 'JoinProduct'-extractProduct :: Functor m => QueryJoin m a -> m ((a, JoinProduct), Duplication)-extractProduct (QueryJoin s) = (second joinProduct *** (fromMaybe All . getLast))- <$> runWriterT (runStateT s primeJoinContext)
− src/Database/Relational/Query/Monad/Trans/JoinState.hs
@@ -1,42 +0,0 @@--- |--- Module : Database.Relational.Query.Monad.Trans.JoinState--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides state definition for--- "Database.Relational.Query.Monad.Trans.Join".------ This is not public interface.-module Database.Relational.Query.Monad.Trans.JoinState (- -- * Join context- JoinContext, primeJoinContext, updateProduct, joinProduct- ) where--import Prelude hiding (product)-import Data.DList (toList)--import Database.Relational.Query.Internal.Sub (ProductBuilder, JoinProduct)-import qualified Database.Relational.Query.Internal.Sub as Product----- | JoinContext type for QueryJoin.-newtype JoinContext =- JoinContext- { product :: Maybe ProductBuilder- }---- | Initial 'JoinContext'.-primeJoinContext :: JoinContext-primeJoinContext = JoinContext Nothing---- | Update product of 'JoinContext'.-updateProduct :: (Maybe ProductBuilder -> ProductBuilder) -> JoinContext -> JoinContext-updateProduct uf ctx = ctx { product = Just . uf . product $ ctx }---- | Finalize context to extract accumulated query product.-joinProduct :: JoinContext -> JoinProduct-joinProduct = fmap (fmap toList . Product.nodeTree) . product
− src/Database/Relational/Query/Monad/Trans/Ordering.hs
@@ -1,122 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Ordering--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which lift--- from query into query with ordering.-module Database.Relational.Query.Monad.Trans.Ordering (- -- * Transformer into query with ordering- Orderings, orderings,-- -- * API of query with ordering- orderBy', orderBy, asc, desc,-- -- * Result- extractOrderingTerms- ) where--import Control.Monad.Trans.Class (MonadTrans (lift))-import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)-import Control.Applicative (Applicative, pure, (<$>))-import Control.Arrow (second)-import Data.DList (DList, toList)--import Database.Relational.Query.Internal.BaseSQL- (Order (..), Nulls (..), OrderColumn, OrderingTerm)--import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Monad.Class- (MonadQualify (..), MonadRestrict(..), MonadQuery(..), MonadAggregate(..), MonadPartition(..))----- | Type to accumulate ordering context.--- Type 'c' is ordering term projection context type.-newtype Orderings c m a =- Orderings (WriterT (DList OrderingTerm) m a)- deriving (MonadTrans, Monad, Functor, Applicative)---- | Lift to 'Orderings'.-orderings :: Monad m => m a -> Orderings c m a-orderings = lift---- | 'MonadRestrict' with ordering.-instance MonadRestrict rc m => MonadRestrict rc (Orderings c m) where- restrict = orderings . restrict---- | 'MonadQualify' with ordering.-instance MonadQualify q m => MonadQualify q (Orderings c m) where- liftQualify = orderings . liftQualify---- | 'MonadQuery' with ordering.-instance MonadQuery m => MonadQuery (Orderings c m) where- setDuplication = orderings . setDuplication- restrictJoin = orderings . restrictJoin- query' = orderings . query'- queryMaybe' = orderings . queryMaybe'---- | 'MonadAggregate' with ordering.-instance MonadAggregate m => MonadAggregate (Orderings c m) where- groupBy = orderings . groupBy- groupBy' = orderings . groupBy'---- | 'MonadPartition' with ordering.-instance MonadPartition c m => MonadPartition c (Orderings c m) where- partitionBy = orderings . partitionBy---- | Ordering term projection type interface.-class ProjectableOrdering p where- orderTerms :: p t -> [OrderColumn]---- | 'Projection' is ordering term.-instance ProjectableOrdering (Projection c) where- orderTerms = Projection.columns---- | Add ordering terms.-updateOrderBys :: (Monad m, ProjectableOrdering (Projection c))- => (Order, Maybe Nulls) -- ^ Order direction- -> Projection c t -- ^ Ordering terms to add- -> Orderings c m () -- ^ Result context with ordering-updateOrderBys opair p = Orderings . mapM_ tell $ terms where- terms = curry pure opair `map` orderTerms p---- | Add ordering terms with null ordering.-orderBy' :: (Monad m, ProjectableOrdering (Projection c))- => Projection c t -- ^ Ordering terms to add- -> Order -- ^ Order direction- -> Nulls -- ^ Order of null- -> Orderings c m () -- ^ Result context with ordering-orderBy' p o n = updateOrderBys (o, Just n) p---- | Add ordering terms.-orderBy :: (Monad m, ProjectableOrdering (Projection c))- => Projection c t -- ^ Ordering terms to add- -> Order -- ^ Order direction- -> Orderings c m () -- ^ Result context with ordering-orderBy p o = updateOrderBys (o, Nothing) p---- | Add ascendant ordering term.-asc :: (Monad m, ProjectableOrdering (Projection c))- => Projection c t -- ^ Ordering terms to add- -> Orderings c m () -- ^ Result context with ordering-asc = updateOrderBys (Asc, Nothing)---- | Add descendant ordering term.-desc :: (Monad m, ProjectableOrdering (Projection c))- => Projection c t -- ^ Ordering terms to add- -> Orderings c m () -- ^ Result context with ordering-desc = updateOrderBys (Desc, Nothing)---- | Run 'Orderings' to get 'OrderingTerms'-extractOrderingTerms :: (Monad m, Functor m) => Orderings c m a -> m (a, [OrderingTerm])-extractOrderingTerms (Orderings oc) = second toList <$> runWriterT oc
− src/Database/Relational/Query/Monad/Trans/Qualify.hs
@@ -1,54 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Qualify--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which qualify uniquely SQL table forms.------ This is not public interface.-module Database.Relational.Query.Monad.Trans.Qualify (- -- * Qualify monad- Qualify, qualify,- evalQualifyPrime, qualifyQuery- ) where--import Control.Monad.Trans.Class (lift)-import Control.Monad.Trans.State (StateT, runStateT, get, modify)-import Control.Applicative (Applicative)-import Control.Monad (liftM, ap)--import qualified Database.Relational.Query.Internal.Sub as Internal----- | Monad type to qualify SQL table forms.-newtype Qualify m a =- Qualify (StateT Int m a)- deriving (Monad, Functor, Applicative)---- | Run qualify monad with initial state to get only result.-evalQualifyPrime :: Monad m => Qualify m a -> m a-evalQualifyPrime (Qualify s) = fst `liftM` runStateT s 0 {- primary alias id -}---- | Generated new qualifier on internal state.-newAlias :: Monad m => Qualify m Internal.Qualifier-newAlias = Qualify $ do- ai <- Internal.Qualifier `liftM` get- modify (+ 1)- return ai---- | Lift to 'Qualify'-qualify :: Monad m => m a -> Qualify m a-qualify = Qualify . lift---- | Get qualifyed table form query.-qualifyQuery :: Monad m- => query -- ^ Query to qualify- -> Qualify m (Internal.Qualified query) -- ^ Result with updated state-qualifyQuery query =- Internal.qualify `liftM` newAlias `ap` return query
− src/Database/Relational/Query/Monad/Trans/Restricting.hs
@@ -1,71 +0,0 @@-{-# LANGUAGE GeneralizedNewtypeDeriving #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}---- |--- Module : Database.Relational.Query.Monad.Trans.Restricting--- Copyright : 2014-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines monad transformer which lift to basic 'MonadQuery'.-module Database.Relational.Query.Monad.Trans.Restricting (- -- * Transformer into restricted context- Restrictings, restrictings,-- -- * Result- extractRestrict- ) where--import Control.Monad.Trans.Class (MonadTrans (lift))-import Control.Monad.Trans.Writer (WriterT, runWriterT, tell)-import Control.Applicative (Applicative, pure, (<$>))-import Control.Arrow (second)-import Data.DList (DList, toList)--import Database.Relational.Query.Sub (QueryRestriction, Projection)-import Database.Relational.Query.Monad.Class- (MonadQualify (..), MonadRestrict(..), MonadQuery (..), MonadAggregate(..))----- | Type to accumulate query restrictions.--- Type 'c' is context tag of restriction building like--- Flat (where) or Aggregated (having).-newtype Restrictings c m a =- Restrictings (WriterT (DList (Projection c (Maybe Bool))) m a)- deriving (MonadTrans, Monad, Functor, Applicative)---- | Lift to 'Restrictings'-restrictings :: Monad m => m a -> Restrictings c m a-restrictings = lift---- | Add whole query restriction.-updateRestriction :: Monad m => Projection c (Maybe Bool) -> Restrictings c m ()-updateRestriction = Restrictings . tell . pure---- | 'MonadRestrict' instance.-instance (Monad q, Functor q) => MonadRestrict c (Restrictings c q) where- restrict = updateRestriction---- | Restricted 'MonadQualify' instance.-instance MonadQualify q m => MonadQualify q (Restrictings c m) where- liftQualify = restrictings . liftQualify---- | Restricted 'MonadQuery' instance.-instance MonadQuery q => MonadQuery (Restrictings c q) where- setDuplication = restrictings . setDuplication- restrictJoin = restrictings . restrictJoin- query' = restrictings . query'- queryMaybe' = restrictings . queryMaybe'---- | Resticted 'MonadAggregate' instance.-instance MonadAggregate m => MonadAggregate (Restrictings c m) where- groupBy = restrictings . groupBy- groupBy' = restrictings . groupBy'---- | Run 'Restrictings' to get 'QueryRestriction'-extractRestrict :: (Monad m, Functor m) => Restrictings c m a -> m (a, QueryRestriction c)-extractRestrict (Restrictings rc) = second toList <$> runWriterT rc
− src/Database/Relational/Query/Monad/Type.hs
@@ -1,38 +0,0 @@--- |--- Module : Database.Relational.Query.Monad.Type--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines core query type.-module Database.Relational.Query.Monad.Type- ( -- * Core query monad- QueryCore, extractCore,- OrderedQuery,- ) where--import Database.Relational.Query.Internal.BaseSQL (Duplication)--import Database.Relational.Query.Sub (JoinProduct, QueryRestriction)-import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Projection (Projection)-import Database.Relational.Query.Projectable (PlaceHolders)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery)-import Database.Relational.Query.Monad.Trans.Join (QueryJoin, extractProduct)-import Database.Relational.Query.Monad.Trans.Restricting (Restrictings, extractRestrict)-import Database.Relational.Query.Monad.Trans.Ordering (Orderings)----- | Core query monad type used from flat(not-aggregated) query and aggregated query.-type QueryCore = Restrictings Flat (QueryJoin ConfigureQuery)---- | Extract 'QueryCore' computation.-extractCore :: QueryCore a- -> ConfigureQuery (((a, QueryRestriction Flat), JoinProduct), Duplication)-extractCore = extractProduct . extractRestrict---- | OrderedQuery monad type with placeholder type 'p'. Projection must be the same as 'Orderings' context type parameter 'c'.-type OrderedQuery c m p r = Orderings c m (PlaceHolders p, Projection c r)
− src/Database/Relational/Query/Monad/Unique.hs
@@ -1,59 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE GeneralizedNewtypeDeriving #-}---- |--- Module : Database.Relational.Query.Monad.Unique--- Copyright : 2014-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module contains definitions about unique query type--- to support scalar queries.-module Database.Relational.Query.Monad.Unique- ( QueryUnique, unsafeUniqueSubQuery,- toSubQuery,- ) where--import Control.Applicative (Applicative)--import Database.Relational.Query.Internal.BaseSQL (Duplication)--import Database.Relational.Query.Context (Flat)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable (PlaceHolders)-import Database.Relational.Query.Monad.Class (MonadQualify, MonadQuery)-import Database.Relational.Query.Monad.Trans.Join (unsafeSubQueryWithAttr)-import Database.Relational.Query.Monad.Trans.Restricting (restrictings)-import Database.Relational.Query.Monad.BaseType (ConfigureQuery, askConfig)-import Database.Relational.Query.Monad.Type (QueryCore, extractCore)-import Database.Relational.Query.Sub- (SubQuery, QueryRestriction, Qualified, JoinProduct, NodeAttr, flatSubQuery)----- | Unique query monad type.-newtype QueryUnique a = QueryUnique (QueryCore a)- deriving (MonadQualify ConfigureQuery, MonadQuery, Monad, Applicative, Functor)---- | Unsafely join sub-query with this unique query.-unsafeUniqueSubQuery :: NodeAttr -- ^ Attribute maybe or just- -> Qualified SubQuery -- ^ 'SubQuery' to join- -> QueryUnique (Projection c r) -- ^ Result joined context and 'SubQuery' result projection.-unsafeUniqueSubQuery a = QueryUnique . restrictings . unsafeSubQueryWithAttr a--extract :: QueryUnique a- -> ConfigureQuery (((a, QueryRestriction Flat), JoinProduct), Duplication)-extract (QueryUnique c) = extractCore c---- | Run 'SimpleQuery' to get 'SubQuery' with 'Qualify' computation.-toSubQuery :: QueryUnique (PlaceHolders p, Projection c r) -- ^ 'QueryUnique' to run- -> ConfigureQuery SubQuery -- ^ Result 'SubQuery' with 'Qualify' computation-toSubQuery q = do- ((((_ph, pj), rs), pd), da) <- extract q- c <- askConfig- return $ flatSubQuery c (Projection.untype pj) da pd rs []
− src/Database/Relational/Query/Pi.hs
@@ -1,42 +0,0 @@--- |--- Module : Database.Relational.Query.Pi--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines typed projection path objects.--- Contains normal interfaces.-module Database.Relational.Query.Pi (- -- * Projection path- Pi, pfmap, pap, pzero, (<.>), (<?.>), (<?.?>),-- id', fst', snd'- ) where--import qualified Control.Category as Category-import Database.Record- (PersistableWidth, persistableWidth, PersistableRecordWidth)-import Database.Record.Persistable- (runPersistableRecordWidth)--import Database.Relational.Query.Pi.Unsafe- (Pi, pfmap, pap, pzero, (<.>), (<?.>), (<?.?>), definePi)----- | Identity projection path.-id' :: Pi a a-id' = Category.id---- | Projection path for fst of tuple.-fst' :: PersistableWidth a => Pi (a, b) a -- ^ Projection path of fst.-fst' = definePi 0--snd'' :: PersistableWidth b => PersistableRecordWidth a -> Pi (a, b) b-snd'' wa = definePi (runPersistableRecordWidth wa)---- | Projection path for snd of tuple.-snd' :: (PersistableWidth a, PersistableWidth b) => Pi (a, b) b -- ^ Projection path of snd.-snd' = snd'' persistableWidth
− src/Database/Relational/Query/Pi/Unsafe.hs
@@ -1,188 +0,0 @@-{-# LANGUAGE ExistentialQuantification #-}-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.Pi.Unsafe--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines typed projection path objects.--- Contains internal structure and unsafe interfaces.-module Database.Relational.Query.Pi.Unsafe (- -- * Projection path- Pi,-- pfmap, pap,-- pzero,-- width', width,-- (<.>), (<?.>), (<?.?>),-- pi,-- definePi, defineDirectPi', defineDirectPi,-- unsafeExpandIndexes',- unsafeExpandIndexes- ) where--import Prelude hiding (pi, (.), id)-import Control.Category (Category (..), (>>>))-import Data.Array (listArray, (!))--import Database.Record.Persistable- (PersistableRecordWidth, runPersistableRecordWidth, unsafePersistableRecordWidth, (<&>),- PersistableWidth (persistableWidth), maybeWidth)--import Database.Relational.Query.ProjectableClass- (ProductConstructor (..), ProjectableFunctor (..), ProjectableApplicative (..), )----- | Projection path primary structure type.-data Pi' r0 r1 = Leftest Int- | Map [Int]--unsafePiAppend' :: Pi' a b' -> Pi' b c' -> Pi' a c-unsafePiAppend' = d where- d (Leftest i) (Leftest j) = Leftest $ i + j- d (Leftest i) (Map js) = Map $ map (i +) js- d (Map is) (Leftest j) = Map $ drop j is- d (Map is) (Map js) = Map [ is' ! j | j <- js ] where- is' = listArray (0, length is) is---- | Projection path from type 'r0' into type 'r1'.--- This type also indicate key object which type is 'r1' for record type 'r0'.-newtype Pi r0 r1 = Pi { runPi :: PersistableRecordWidth r0 -> (Pi' r0 r1, PersistableRecordWidth r1) }--instance PersistableWidth r0 => Show (Pi r0 r1) where- show p = unwords ["Pi", show $ unsafeExpandIndexes p]--unsafePiAppend :: (PersistableRecordWidth b' -> PersistableRecordWidth b)- -> (PersistableRecordWidth c' -> PersistableRecordWidth c)- -> Pi a b' -> Pi b c' -> Pi a c-unsafePiAppend wbf wcf (Pi f) (Pi g) = Pi $ \wa ->- let (pab, wb) = f wa- (pbc, wc) = g $ wbf wb- in (pab `unsafePiAppend'` pbc, wcf wc)---- | Unsafely untype key to expand indexes.-unsafeExpandIndexes' :: PersistableRecordWidth a -> Pi a b -> [Int]-unsafeExpandIndexes' wa (Pi f) = d $ f wa where- d (Map is, _) = is- d (Leftest i, w) = [ i .. i + w' - 1 ] where- w' = runPersistableRecordWidth w---- | Unsafely untype key to expand indexes.-unsafeExpandIndexes :: PersistableWidth a => Pi a b -> [Int]-unsafeExpandIndexes = unsafeExpandIndexes' persistableWidth---- | Unsafely cast width proof object of record. Result record must be same width.-unsafeCastRecordWidth :: PersistableRecordWidth a -> PersistableRecordWidth a'-unsafeCastRecordWidth = unsafePersistableRecordWidth . runPersistableRecordWidth--unsafeCast :: Pi a b' -> Pi a b-unsafeCast = c where- d (Leftest i) = Leftest i- d (Map m) = Map m- c (Pi f) = Pi $ \wa ->- let (pb, wb) = f wa in- (d pb, unsafeCastRecordWidth wb)---- | Projectable fmap of 'Pi' type.-pfmap :: ProductConstructor (a -> b)- => (a -> b) -> Pi r a -> Pi r b-_ `pfmap` p = unsafeCast p---- | Projectable ap of 'Pi' type.-pap :: Pi r (a -> b) -> Pi r a -> Pi r b-pap pab pb =- Pi $ \wr ->- let (_, wab) = runPi pab wr- (_, wb) = runPi pb wr in- (Map $ unsafeExpandIndexes' wr pab ++ unsafeExpandIndexes' wr pb,- unsafeCastRecordWidth $ wab <&> wb) {- should switch to safe projectable-applicative -}---- | Compose seed of projection path 'Pi' which has record result type.-instance ProjectableFunctor (Pi a) where- (|$|) = pfmap---- | Compose projection path 'Pi' which has record result type using applicative style.-instance ProjectableApplicative (Pi a) where- (|*|) = pap---- | 'Pi' with zero width which projects to unit-pzero :: Pi a ()-pzero = Pi $ \_ -> (Map [], persistableWidth)---- | Get record width proof object.-width' :: PersistableWidth r => Pi r ct -> PersistableRecordWidth ct-width' (Pi f) = snd $ f persistableWidth---- | Get record width.-width :: PersistableWidth r => Pi r a -> Int-width = runPersistableRecordWidth . width'--justWidth :: PersistableRecordWidth (Maybe a) -> PersistableRecordWidth a-justWidth = unsafeCastRecordWidth---instance Category Pi where- id = Pi $ \pw -> (Leftest 0, pw)- Pi fb . Pi fa = Pi $ \wa ->- let (pb, wb) = fa wa- (pc, wc) = fb wb- in (unsafePiAppend' pb pc, wc)---- | Compose projection path.-(<.>) :: Pi a b -> Pi b c -> Pi a c-(<.>) = (>>>)---- | Compose projection path. 'Maybe' phantom functor is 'map'-ed.-(<?.>) :: Pi a (Maybe b) -> Pi b c -> Pi a (Maybe c)-(<?.>) = unsafePiAppend justWidth maybeWidth---- | Compose projection path. 'Maybe' phantom functors are 'join'-ed like '>=>'.-(<?.?>) :: Pi a (Maybe b) -> Pi b (Maybe c) -> Pi a (Maybe c)-(<?.?>) = unsafePiAppend justWidth id--infixl 8 <.>, <?.>, <?.?>---- | Unsafely project untyped value list.-pi :: PersistableRecordWidth r0 -> Pi r0 r1 -> [a] -> [a]-pi w0 (Pi f) cs = d p' where- (p', w1) = f w0- d (Leftest i) = take (runPersistableRecordWidth w1) . drop i $ cs- d (Map is) = [cs' ! i | i <- is]- cs' = listArray (0, length cs) cs---- | Unsafely define projection path from type 'r0' into type 'r1'.-definePi' :: PersistableRecordWidth r1- -> Int -- ^ Index of flat SQL value list- -> Pi r0 r1 -- ^ Result projection path-definePi' pw i = Pi $ \_ -> (Leftest i, pw)---- | Unsafely define projection path from type 'r0' into type 'r1'.--- Use inferred 'PersistableRecordWidth'.-definePi :: PersistableWidth r1- => Int -- ^ Index of flat SQL value list- -> Pi r0 r1 -- ^ Result projection path-definePi = definePi' persistableWidth---- | Unsafely define projection path from type 'r0' into type 'r1'.-defineDirectPi' :: PersistableRecordWidth r1- -> [Int] -- ^ Indexes of flat SQL value list- -> Pi r0 r1 -- ^ Result projection path-defineDirectPi' pw is = Pi $ \_ -> (Map is, pw)---- | Unsafely define projection path from type 'r0' into type 'r1'.--- Use inferred 'PersistableRecordWidth'.-defineDirectPi :: PersistableWidth r1- => [Int] -- ^ Indexes of flat SQL value list- -> Pi r0 r1 -- ^ Result projection path-defineDirectPi = defineDirectPi' persistableWidth
− src/Database/Relational/Query/Projectable.hs
@@ -1,551 +0,0 @@-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE OverloadedStrings #-}---- |--- Module : Database.Relational.Query.Projectable--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines operators on various polymorphic projections.-module Database.Relational.Query.Projectable (- -- * Projectable from SQL strings- SqlProjectable (unsafeProjectSqlTerms), unsafeProjectSql',- unsafeProjectSql,-- -- * Projections of values- value,- valueTrue, valueFalse,- values,- nothing, unsafeValueNull,-- -- * Placeholders- PlaceHolders, unsafeAddPlaceHolders, unsafePlaceHolders,- pwPlaceholder, placeholder', placeholder, unitPlaceHolder, unitPH,-- -- * Projectable into SQL strings- ProjectableShowSql (unsafeShowSql'), unsafeShowSql,-- -- * Operators- (.=.), (.<.), (.<=.), (.>.), (.>=.), (.<>.),-- and', or', in',-- (.||.), (?||?), like, likeMaybe, like', likeMaybe',- (.+.), (.-.), (.*.), (./.),- (?+?), (?-?), (?*?), (?/?),-- isNothing, isJust, fromMaybe,- not', exists,-- negate', fromIntegral', showNum,- negateMaybe, fromIntegralMaybe, showNumMaybe,-- casesOrElse, casesOrElse',- caseSearch, caseSearchMaybe, case', caseMaybe,-- SqlBinOp, unsafeBinOp, unsafeUniOp,-- -- * Terms for Window function types- rank, denseRank, rowNumber, percentRank, cumeDist,-- -- * Zipping projections- projectZip, (><),- ProjectableIdZip (..),-- -- * 'Maybe' type projecitoins- ProjectableMaybe (just, flattenMaybe),- ) where--import Prelude hiding (pi)--import Data.String (IsString)--import Language.SQL.Keyword (Keyword)-import qualified Language.SQL.Keyword as SQL--import Database.Record- (PersistableWidth, persistableWidth, PersistableRecordWidth,- HasColumnConstraint, NotNull)-import Database.Record.Persistable (runPersistableRecordWidth)--import Database.Relational.Query.Internal.SQL (StringSQL, stringSQL, showStringSQL)-import qualified Database.Relational.Query.Internal.Sub as Internal--import Database.Relational.Query.ProjectableClass- (ProjectableFunctor (..), ProjectableApplicative (..), )-import Database.Relational.Query.Context (Flat, Aggregated, Exists, OverWindow)-import Database.Relational.Query.TupleInstances ()-import Database.Relational.Query.ProjectableClass- (ShowConstantTermsSQL, showConstantTermsSQL, )-import Database.Relational.Query.Projection- (Projection, ListProjection)-import qualified Database.Relational.Query.Projection as Projection----- | Interface to project SQL terms unsafely.-class SqlProjectable p where- -- | Unsafely project from SQL expression terms.- unsafeProjectSqlTerms :: [StringSQL] -- ^ SQL expression strings- -> p t -- ^ Result projection object---- | Unsafely make 'Projection' from SQL terms.-instance SqlProjectable (Projection Flat) where- unsafeProjectSqlTerms = Projection.unsafeFromSqlTerms---- | Unsafely make 'Projection' from SQL terms.-instance SqlProjectable (Projection Aggregated) where- unsafeProjectSqlTerms = Projection.unsafeFromSqlTerms---- | Unsafely make 'Projection' from SQL terms.-instance SqlProjectable (Projection OverWindow) where- unsafeProjectSqlTerms = Projection.unsafeFromSqlTerms--class SqlProjectable p => OperatorProjectable p-instance OperatorProjectable (Projection Flat)-instance OperatorProjectable (Projection Aggregated)---- | Unsafely Project single SQL term.-unsafeProjectSql' :: SqlProjectable p => StringSQL -> p t-unsafeProjectSql' = unsafeProjectSqlTerms . (:[])---- | Unsafely Project single SQL string. String interface of 'unsafeProjectSql''.-unsafeProjectSql :: SqlProjectable p => String -> p t-unsafeProjectSql = unsafeProjectSql' . stringSQL---- | Polymorphic projection of SQL null value. Semantics of comparing is unsafe.-nothing :: (OperatorProjectable (Projection c), SqlProjectable (Projection c), PersistableWidth a)- => Projection c (Maybe a)-nothing = proxyWidth persistableWidth- where- proxyWidth :: SqlProjectable (Projection c) => PersistableRecordWidth a -> Projection c (Maybe a)- proxyWidth w = unsafeProjectSqlTerms $ replicate (runPersistableRecordWidth w) SQL.NULL--{-# DEPRECATED unsafeValueNull "Use `nothing' instead of this." #-}--- | Deprecated. Polymorphic projection of SQL null value.-unsafeValueNull :: (OperatorProjectable (Projection c), SqlProjectable (Projection c), PersistableWidth a)- => Projection c (Maybe a)-unsafeValueNull = nothing---- | Generate polymorphic projection of SQL constant values from Haskell value.-value :: (ShowConstantTermsSQL t, OperatorProjectable p) => t -> p t-value = unsafeProjectSqlTerms . showConstantTermsSQL---- | Polymorphic proejction of SQL true value.-valueTrue :: (OperatorProjectable p, ProjectableMaybe p) => p (Maybe Bool)-valueTrue = just $ value True---- | Polymorphic proejction of SQL false value.-valueFalse :: (OperatorProjectable p, ProjectableMaybe p) => p (Maybe Bool)-valueFalse = just $ value False---- | Polymorphic proejction of SQL set value from Haskell list.-values :: (ShowConstantTermsSQL t, OperatorProjectable p) => [t] -> ListProjection p t-values = Projection.list . map value----- | Interface to get SQL term from projections.-class ProjectableShowSql p where- -- | Unsafely generate SQL expression term from projection object.- unsafeShowSql' :: p a -- ^ Source projection object- -> StringSQL -- ^ Result SQL expression string.---- | Unsafely generate SQL expression string from projection object.--- String interface of 'unsafeShowSql''.-unsafeShowSql :: ProjectableShowSql p- => p a -- ^ Source projection object- -> String -- ^ Result SQL expression string.-unsafeShowSql = showStringSQL . unsafeShowSql'---- | Unsafely get SQL term from 'Proejction'.-instance ProjectableShowSql (Projection c) where- unsafeShowSql' = Projection.unsafeStringSql----- | Binary operator type for SQL String.-type SqlBinOp = Keyword -> Keyword -> Keyword---- | Unsafely make projection unary operator from SQL keyword.-unsafeUniOp :: (ProjectableShowSql p0, SqlProjectable p1)- => (Keyword -> Keyword) -> p0 a -> p1 b-unsafeUniOp u = unsafeProjectSql' . u . unsafeShowSql'--unsafeFlatUniOp :: (SqlProjectable p, ProjectableShowSql p)- => Keyword -> p a -> p b-unsafeFlatUniOp kw = unsafeUniOp (SQL.paren . SQL.defineUniOp kw)---- | Unsafely make projection binary operator from string binary operator.-unsafeBinOp :: (SqlProjectable p, ProjectableShowSql p)- => SqlBinOp- -> p a -> p b -> p c-unsafeBinOp op a b = unsafeProjectSql' . SQL.paren $- op (unsafeShowSql' a) (unsafeShowSql' b)---- | Unsafely make compare projection binary operator from string binary operator.-compareBinOp :: (SqlProjectable p, ProjectableShowSql p)- => SqlBinOp- -> p a -> p a -> p (Maybe Bool)-compareBinOp = unsafeBinOp---- | Unsafely make numrical projection binary operator from string binary operator.-monoBinOp :: (SqlProjectable p, ProjectableShowSql p)- => SqlBinOp- -> p a -> p a -> p a-monoBinOp = unsafeBinOp----- | Compare operator corresponding SQL /=/ .-(.=.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.=.) = compareBinOp (SQL..=.)---- | Compare operator corresponding SQL /</ .-(.<.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.<.) = compareBinOp (SQL..<.)---- | Compare operator corresponding SQL /<=/ .-(.<=.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.<=.) = compareBinOp (SQL..<=.)---- | Compare operator corresponding SQL />/ .-(.>.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.>.) = compareBinOp (SQL..>.)---- | Compare operator corresponding SQL />=/ .-(.>=.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.>=.) = compareBinOp (SQL..>=.)---- | Compare operator corresponding SQL /<>/ .-(.<>.) :: (OperatorProjectable p, ProjectableShowSql p)- => p ft -> p ft -> p (Maybe Bool)-(.<>.) = compareBinOp (SQL..<>.)---- | Logical operator corresponding SQL /AND/ .-and' :: (OperatorProjectable p, ProjectableShowSql p)- => p (Maybe Bool) -> p (Maybe Bool) -> p (Maybe Bool)-and' = monoBinOp SQL.and---- | Logical operator corresponding SQL /OR/ .-or' :: (OperatorProjectable p, ProjectableShowSql p)- => p (Maybe Bool) -> p (Maybe Bool) -> p (Maybe Bool)-or' = monoBinOp SQL.or---- | Logical operator corresponding SQL /NOT/ .-not' :: (OperatorProjectable p, ProjectableShowSql p)- => p (Maybe Bool) -> p (Maybe Bool)-not' = unsafeFlatUniOp SQL.NOT---- | Logical operator corresponding SQL /EXISTS/ .-exists :: (OperatorProjectable p, ProjectableShowSql p)- => ListProjection (Projection Exists) r -> p (Maybe Bool)-exists = unsafeProjectSql' . SQL.paren . SQL.defineUniOp SQL.EXISTS- . Projection.unsafeStringSqlList unsafeShowSql'---- | Concatinate operator corresponding SQL /||/ .-(.||.) :: (OperatorProjectable p, ProjectableShowSql p, IsString a)- => p a -> p a -> p a-(.||.) = unsafeBinOp (SQL..||.)---- | Concatinate operator corresponding SQL /||/ . Maybe type version.-(?||?) :: (OperatorProjectable p, ProjectableShowSql p, IsString a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe a)-(?||?) = unsafeBinOp (SQL..||.)--unsafeLike :: (OperatorProjectable p, ProjectableShowSql p)- => p a -> p b -> p (Maybe Bool)-unsafeLike = unsafeBinOp (SQL.defineBinOp SQL.LIKE)---- | String-compare operator corresponding SQL /LIKE/ .-like' :: (OperatorProjectable p, ProjectableShowSql p, IsString a)- => p a -> p a -> p (Maybe Bool)-x `like'` y = x `unsafeLike` y---- | String-compare operator corresponding SQL /LIKE/ .-likeMaybe' :: (OperatorProjectable p, ProjectableShowSql p, IsString a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe Bool)-x `likeMaybe'` y = x `unsafeLike` y---- | String-compare operator corresponding SQL /LIKE/ .-like :: (OperatorProjectable p, ProjectableShowSql p, IsString a, ShowConstantTermsSQL a)- => p a -> a -> p (Maybe Bool)-x `like` a = x `like'` value a---- | String-compare operator corresponding SQL /LIKE/ . Maybe type version.-likeMaybe :: (OperatorProjectable p, ProjectableShowSql p, IsString a, ShowConstantTermsSQL a)- => p (Maybe a) -> a -> p (Maybe Bool)-x `likeMaybe` a = x `unsafeLike` value a---- | Unsafely make number projection binary operator from SQL operator string.-monoBinOp' :: (SqlProjectable p, ProjectableShowSql p)- => Keyword -> p a -> p a -> p a-monoBinOp' = monoBinOp . SQL.defineBinOp---- | Number operator corresponding SQL /+/ .-(.+.) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p a -> p a -> p a-(.+.) = monoBinOp' "+"---- | Number operator corresponding SQL /-/ .-(.-.) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p a -> p a -> p a-(.-.) = monoBinOp' "-"---- | Number operator corresponding SQL /// .-(./.) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p a -> p a -> p a-(./.) = monoBinOp' "/"---- | Number operator corresponding SQL /*/ .-(.*.) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p a -> p a -> p a-(.*.) = monoBinOp' "*"---- | Number negate uni-operator corresponding SQL /-/.-negate' :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p a -> p a-negate' = unsafeFlatUniOp $ SQL.word "-"--unsafeCastProjectable :: (SqlProjectable p, ProjectableShowSql p)- => p a -> p b-unsafeCastProjectable = unsafeProjectSql' . unsafeShowSql'---- | Number fromIntegral uni-operator.-fromIntegral' :: (SqlProjectable p, ProjectableShowSql p, Integral a, Num b)- => p a -> p b-fromIntegral' = unsafeCastProjectable---- | Unsafely show number into string-like type in projections.-showNum :: (SqlProjectable p, ProjectableShowSql p, Num a, IsString b)- => p a -> p b-showNum = unsafeCastProjectable---- | Number operator corresponding SQL /+/ .-(?+?) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe a)-(?+?) = monoBinOp' "+"---- | Number operator corresponding SQL /-/ .-(?-?) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe a)-(?-?) = monoBinOp' "-"---- | Number operator corresponding SQL /// .-(?/?) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe a)-(?/?) = monoBinOp' "/"---- | Number operator corresponding SQL /*/ .-(?*?) :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p (Maybe a) -> p (Maybe a) -> p (Maybe a)-(?*?) = monoBinOp' "*"---- | Number negate uni-operator corresponding SQL /-/.-negateMaybe :: (OperatorProjectable p, ProjectableShowSql p, Num a)- => p (Maybe a) -> p (Maybe a)-negateMaybe = unsafeFlatUniOp $ SQL.word "-"---- | Number fromIntegral uni-operator.-fromIntegralMaybe :: (SqlProjectable p, ProjectableShowSql p, Integral a, Num b)- => p (Maybe a) -> p (Maybe b)-fromIntegralMaybe = unsafeCastProjectable---- | Unsafely show number into string-like type in projections.-showNumMaybe :: (SqlProjectable p, ProjectableShowSql p, Num a, IsString b)- => p (Maybe a) -> p (Maybe b)-showNumMaybe = unsafeCastProjectable---- | Search case operator correnponding SQL search /CASE/.--- Like, /CASE WHEN p0 THEN a WHEN p1 THEN b ... ELSE c END/-caseSearch :: OperatorProjectable (Projection c)- => [(Projection c (Maybe Bool), Projection c a)] -- ^ Each when clauses- -> Projection c a -- ^ Else result projection- -> Projection c a -- ^ Result projection-caseSearch = Internal.caseSearch---- | Same as 'caseSearch', but you can write like <when list> `casesOrElse` <else clause>.-casesOrElse :: OperatorProjectable (Projection c)- => [(Projection c (Maybe Bool), Projection c a)] -- ^ Each when clauses- -> Projection c a -- ^ Else result projection- -> Projection c a -- ^ Result projection-casesOrElse = caseSearch---- | Null default version of 'caseSearch'.-caseSearchMaybe :: (OperatorProjectable (Projection c) {- (Projection c) is always ProjectableMaybe -}, PersistableWidth a)- => [(Projection c (Maybe Bool), Projection c (Maybe a))] -- ^ Each when clauses- -> Projection c (Maybe a) -- ^ Result projection-caseSearchMaybe cs = caseSearch cs unsafeValueNull---- | Simple case operator correnponding SQL simple /CASE/.--- Like, /CASE x WHEN v THEN a WHEN w THEN b ... ELSE c END/-case' :: OperatorProjectable (Projection c)- => Projection c a -- ^ Projection value to match- -> [(Projection c a, Projection c b)] -- ^ Each when clauses- -> Projection c b -- ^ Else result projection- -> Projection c b -- ^ Result projection-case' = Internal.case'---- | Uncurry version of 'case'', and you can write like ... `casesOrElse'` <else clause>.-casesOrElse' :: OperatorProjectable (Projection c)- => (Projection c a, [(Projection c a, Projection c b)]) -- ^ Projection value to match and each when clauses list- -> Projection c b -- ^ Else result projection- -> Projection c b -- ^ Result projection-casesOrElse' = uncurry case'---- | Null default version of 'case''.-caseMaybe :: (OperatorProjectable (Projection c) {- (Projection c) is always ProjectableMaybe -}, PersistableWidth b)- => Projection c a -- ^ Projection value to match- -> [(Projection c a, Projection c (Maybe b))] -- ^ Each when clauses- -> Projection c (Maybe b) -- ^ Result projection-caseMaybe v cs = case' v cs unsafeValueNull---- | Binary operator corresponding SQL /IN/ .-in' :: (OperatorProjectable p, ProjectableShowSql p)- => p t -> ListProjection p t -> p (Maybe Bool)-in' a lp = unsafeProjectSql' . SQL.paren- $ SQL.in' (unsafeShowSql' a) (Projection.unsafeStringSqlList unsafeShowSql' lp)---- | Operator corresponding SQL /IS NULL/ , and extended against record types.-isNothing :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r)- => Projection c (Maybe r) -> Projection c (Maybe Bool)-isNothing mr = unsafeProjectSql' $- SQL.paren $ (SQL.defineBinOp SQL.IS)- (Projection.unsafeStringSqlNotNullMaybe mr) SQL.NULL---- | Operator corresponding SQL /NOT (... IS NULL)/ , and extended against record type.-isJust :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r)- => Projection c (Maybe r) -> Projection c (Maybe Bool)-isJust = not' . isNothing---- | Operator from maybe type using record extended 'isNull'.-fromMaybe :: (OperatorProjectable (Projection c), ProjectableShowSql (Projection c), HasColumnConstraint NotNull r)- => Projection c r -> Projection c (Maybe r) -> Projection c r-fromMaybe d p = [ (isNothing p, d) ] `casesOrElse` unsafeCastProjectable p--unsafeUniTermFunction :: SqlProjectable p => Keyword -> p t-unsafeUniTermFunction = unsafeProjectSql' . (SQL.<++> stringSQL "()")---- | /RANK()/ term.-rank :: Integral a => Projection OverWindow a-rank = unsafeUniTermFunction SQL.RANK---- | /DENSE_RANK()/ term.-denseRank :: Integral a => Projection OverWindow a-denseRank = unsafeUniTermFunction SQL.DENSE_RANK---- | /ROW_NUMBER()/ term.-rowNumber :: Integral a => Projection OverWindow a-rowNumber = unsafeUniTermFunction SQL.ROW_NUMBER---- | /PERCENT_RANK()/ term.-percentRank :: Projection OverWindow Double-percentRank = unsafeUniTermFunction SQL.PERCENT_RANK---- | /CUME_DIST()/ term.-cumeDist :: Projection OverWindow Double-cumeDist = unsafeUniTermFunction SQL.CUME_DIST---- | Placeholder parameter type which has real parameter type arguemnt 'p'.-data PlaceHolders p = PlaceHolders---- | Unsafely add placeholder parameter to queries.-unsafeAddPlaceHolders :: Functor f => f a -> f (PlaceHolders p, a)-unsafeAddPlaceHolders = fmap ((,) PlaceHolders)---- | Unsafely get placeholder parameter-unsafePlaceHolders :: PlaceHolders p-unsafePlaceHolders = PlaceHolders---- | No placeholder semantics-unitPlaceHolder :: PlaceHolders ()-unitPlaceHolder = unsafePlaceHolders---- | No placeholder semantics. Same as `unitPlaceHolder`-unitPH :: PlaceHolders ()-unitPH = unitPlaceHolder---- | Unsafely cast placeholder parameter type.-unsafeCastPlaceHolders :: PlaceHolders a -> PlaceHolders b-unsafeCastPlaceHolders PlaceHolders = PlaceHolders---- | Provide scoped placeholder from width and return its parameter object.-pwPlaceholder :: SqlProjectable p- => PersistableRecordWidth a- -> (p a -> b)- -> (PlaceHolders a, b)-pwPlaceholder pw f = (PlaceHolders, f $ projectPlaceHolder pw)- where- projectPlaceHolder :: SqlProjectable p- => PersistableRecordWidth a- -> p a- projectPlaceHolder = unsafeProjectSqlTerms . (`replicate` "?") . runPersistableRecordWidth---- | Provide scoped placeholder and return its parameter object.-placeholder' :: (PersistableWidth t, SqlProjectable p) => (p t -> a) -> (PlaceHolders t, a)-placeholder' = pwPlaceholder persistableWidth---- | Provide scoped placeholder and return its parameter object. Monadic version.-placeholder :: (PersistableWidth t, SqlProjectable p, Monad m) => (p t -> m a) -> m (PlaceHolders t, a)-placeholder f = do- let (ph, ma) = placeholder' f- a <- ma- return (ph, a)----- | Zipping projections.-projectZip :: ProjectableApplicative p => p a -> p b -> p (a, b)-projectZip pa pb = (,) |$| pa |*| pb---- | Binary operator the same as 'projectZip'.-(><) :: ProjectableApplicative p => p a -> p b -> p (a, b)-(><) = projectZip---- | Interface to control 'Maybe' of phantom type in projections.-class ProjectableMaybe p where- -- | Cast projection phantom type into 'Maybe'.- just :: p a -> p (Maybe a)- -- | Compose nested 'Maybe' phantom type on projection.- flattenMaybe :: p (Maybe (Maybe a)) -> p (Maybe a)---- | Control phantom 'Maybe' type in placeholder parameters.-instance ProjectableMaybe PlaceHolders where- just = unsafeCastPlaceHolders- flattenMaybe = unsafeCastPlaceHolders---- | Control phantom 'Maybe' type in projection type 'Projection'.-instance ProjectableMaybe (Projection c) where- just = Projection.just- flattenMaybe = Projection.flattenMaybe---- | Zipping except for identity element laws.-class ProjectableApplicative p => ProjectableIdZip p where- leftId :: p ((), a) -> p a- rightId :: p (a, ()) -> p a---- | Zipping except for identity element laws against placeholder parameter type.-instance ProjectableIdZip PlaceHolders where- leftId = unsafeCastPlaceHolders- rightId = unsafeCastPlaceHolders---- | Compose seed of record type 'PlaceHolders'.-instance ProjectableFunctor PlaceHolders where- _ |$| PlaceHolders = PlaceHolders---- | Compose record type 'PlaceHolders' using applicative style.-instance ProjectableApplicative PlaceHolders where- pf |*| pa = unsafeCastPlaceHolders (pf >< pa)--infixl 7 .*., ./., ?*?, ?/?-infixl 6 .+., .-., ?+?, ?-?-infixl 5 .||., ?||?-infix 4 .=., .<>., .>., .>=., .<., .<=., `in'`, `like`, `likeMaybe`, `like'`, `likeMaybe'`-infixr 3 `and'`-infixr 2 `or'`-infixl 1 ><
− src/Database/Relational/Query/ProjectableClass.hs
@@ -1,102 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}-{-# LANGUAGE TypeOperators #-}-{-# LANGUAGE DefaultSignatures #-}---- |--- Module : Database.Relational.Query.ProjectableClass--- Copyright : 2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module provides interfaces to preserve constraints of--- direct product projections.-module Database.Relational.Query.ProjectableClass (- -- * Interface to specify record constructors.- ProductConstructor (..),-- -- * ProjectableFunctor and ProjectableApplicative- ProjectableFunctor (..), ProjectableApplicative (..), ipfmap,-- -- * Literal SQL terms- ShowConstantTermsSQL (..), showConstantTermsSQL,- StringSQL,-- ) where--import GHC.Generics (Generic, Rep, U1 (..), K1 (..), M1 (..), (:*:)(..), from)-import Data.Monoid (mempty, (<>))-import Data.DList (DList, toList)--import Database.Relational.Query.Internal.SQL (StringSQL)----- | Specify tuple like record constructors which are allowed to define 'ProjectableFunctor'.-class ProductConstructor r where- -- | The constructor which has type 'r'.- productConstructor :: r---- | Weaken functor on projections.-class ProjectableFunctor p where- -- | Method like 'fmap'.- (|$|) :: ProductConstructor (a -> b) => (a -> b) -> p a -> p b---- | Same as '|$|' other than using inferred record constructor.-ipfmap :: (ProjectableFunctor p, ProductConstructor (a -> b))- => p a -> p b-ipfmap = (|$|) productConstructor---- | Weaken applicative functor on projections.-class ProjectableFunctor p => ProjectableApplicative p where- -- | Method like '<*>'.- (|*|) :: p (a -> b) -> p a -> p b--infixl 4 |$|, |*|----- | Convert from haskell record to SQL terms list.-showConstantTermsSQL :: ShowConstantTermsSQL a- => a- -> [StringSQL]-showConstantTermsSQL = toList . showConstantTermsSQL'--{- |-'ShowConstantTermsSQL' 'a' is implicit rule to derive function to convert-from haskell record type 'a' into constant SQL terms.--Generic programming (<https://downloads.haskell.org/~ghc/latest/docs/html/users_guide/glasgow_exts.html#generic-programming>)-with default signature is available for 'ShowConstantTermsSQL' class,-so you can make instance like below:--@- \{\-\# LANGUAGE DeriveGeneric \#\-\}- import GHC.Generics (Generic)- --- data Foo = Foo { ... } deriving Generic- instance ShowConstantTermsSQL Foo-@---}-class ShowConstantTermsSQL a where- showConstantTermsSQL' :: a -> DList StringSQL-- default showConstantTermsSQL' :: (Generic a, GShowConstantTermsSQL (Rep a)) => a -> DList StringSQL- showConstantTermsSQL' = gShowConstantTermsSQL . from--class GShowConstantTermsSQL f where- gShowConstantTermsSQL :: f a -> DList StringSQL--instance GShowConstantTermsSQL U1 where- gShowConstantTermsSQL U1 = mempty--instance (GShowConstantTermsSQL a, GShowConstantTermsSQL b) =>- GShowConstantTermsSQL (a :*: b) where- gShowConstantTermsSQL (a :*: b) = gShowConstantTermsSQL a <> gShowConstantTermsSQL b--instance GShowConstantTermsSQL a => GShowConstantTermsSQL (M1 i c a) where- gShowConstantTermsSQL (M1 a) = gShowConstantTermsSQL a--instance ShowConstantTermsSQL a => GShowConstantTermsSQL (K1 i a) where- gShowConstantTermsSQL (K1 a) = showConstantTermsSQL' a
− src/Database/Relational/Query/ProjectableExtended.hs
@@ -1,201 +0,0 @@-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.ProjectableExtended--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines operators on various polymorphic projections--- which needs extended GHC features.-module Database.Relational.Query.ProjectableExtended (- -- * Projection for nested 'Maybe's- ProjectableFlattenMaybe (flatten),-- flattenPiMaybe,-- -- * Get narrower projections- (!), (?!), (?!?), (!??),-- -- * Aggregate functions- unsafeAggregateOp,- count,- sum', sumMaybe, avg, avgMaybe,- max', maxMaybe, min', minMaybe,- every, any', some',-- -- * Zipping projection type trick- ProjectableIdZip (leftId, rightId),- ProjectableRunIdsZip (runIds), flattenPh- -- generalizedZip', (>?<)- ) where--import Prelude hiding (pi)--import qualified Language.SQL.Keyword as SQL-import Database.Record (PersistableWidth)--import Database.Relational.Query.Context (Flat, Aggregated, OverWindow)-import Database.Relational.Query.Projection (Projection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable- (PlaceHolders, unsafeUniOp,- ProjectableMaybe (flattenMaybe), ProjectableIdZip (leftId, rightId),- SqlProjectable)-import Database.Relational.Query.Pi (Pi)---class AggregatedContext ac-instance AggregatedContext Aggregated-instance AggregatedContext OverWindow---- | Unsafely make aggregation uni-operator from SQL keyword.-unsafeAggregateOp :: (AggregatedContext ac, SqlProjectable (p ac))- => SQL.Keyword -> Projection Flat a -> p ac b-unsafeAggregateOp op = unsafeUniOp ((op SQL.<++>) . SQL.paren)---- | Aggregation function COUNT.-count :: (Integral b, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat a -> p ac b-count = unsafeAggregateOp SQL.COUNT---- | Aggregation function SUM.-sumMaybe :: (Num a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe a) -> p ac (Maybe a)-sumMaybe = unsafeAggregateOp SQL.SUM---- | Aggregation function SUM.-sum' :: (Num a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat a -> p ac (Maybe a)-sum' = sumMaybe . Projection.just---- | Aggregation function AVG.-avgMaybe :: (Num a, Fractional b, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe a) -> p ac (Maybe b)-avgMaybe = unsafeAggregateOp SQL.AVG---- | Aggregation function AVG.-avg :: (Num a, Fractional b, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat a -> p ac (Maybe b)-avg = avgMaybe . Projection.just---- | Aggregation function MAX.-maxMaybe :: (Ord a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe a) -> p ac (Maybe a)-maxMaybe = unsafeAggregateOp SQL.MAX---- | Aggregation function MAX.-max' :: (Ord a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat a -> p ac (Maybe a)-max' = maxMaybe . Projection.just---- | Aggregation function MIN.-minMaybe :: (Ord a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe a) -> p ac (Maybe a)-minMaybe = unsafeAggregateOp SQL.MIN---- | Aggregation function MIN.-min' :: (Ord a, AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat a -> p ac (Maybe a)-min' = minMaybe . Projection.just---- | Aggregation function EVERY.-every :: (AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)-every = unsafeAggregateOp SQL.EVERY---- | Aggregation function ANY.-any' :: (AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)-any' = unsafeAggregateOp SQL.ANY---- | Aggregation function SOME.-some' :: (AggregatedContext ac, SqlProjectable (p ac))- => Projection Flat (Maybe Bool) -> p ac (Maybe Bool)-some' = unsafeAggregateOp SQL.SOME---- | Get narrower projection along with projection path.-(!) :: PersistableWidth a- => Projection c a -- ^ Source projection- -> Pi a b -- ^ Projection path- -> Projection c b -- ^ Narrower projected object-(!) = Projection.pi---- | Get narrower projection along with projection path--- 'Maybe' phantom functor is 'map'-ed.-(?!) :: PersistableWidth a- => Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type- -> Pi a b -- ^ Projection path- -> Projection c (Maybe b) -- ^ Narrower projected object. 'Maybe' type result-(?!) = Projection.piMaybe---- | Get narrower projection along with projection path--- and project into result projection type.--- Source record 'Maybe' phantom functor and projection path leaf 'Maybe' functor are 'join'-ed.-(?!?) :: PersistableWidth a- => Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type- -> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf- -> Projection c (Maybe b) -- ^ Narrower projected object. 'Maybe' phantom type result-(?!?) = Projection.piMaybe'----- | Interface to compose phantom 'Maybe' nested type.-class ProjectableFlattenMaybe a b where- flatten :: ProjectableMaybe p => p a -> p b---- | Compose 'Maybe' type in projection phantom type.-instance ProjectableFlattenMaybe (Maybe a) b- => ProjectableFlattenMaybe (Maybe (Maybe a)) b where- flatten = flatten . flattenMaybe---- | Not 'Maybe' type is not processed.-instance ProjectableFlattenMaybe (Maybe a) (Maybe a) where- flatten = id---- | Get narrower projection with flatten leaf phantom Maybe types along with projection path.-flattenPiMaybe :: (PersistableWidth a, ProjectableMaybe (Projection cont), ProjectableFlattenMaybe (Maybe b) c)- => Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type- -> Pi a b -- ^ Projection path- -> Projection cont c -- ^ Narrower 'Projection'. Flatten 'Maybe' phantom type-flattenPiMaybe p = flatten . Projection.piMaybe p---- | Get narrower projection with flatten leaf phantom Maybe types along with projection path.-(!??) :: (PersistableWidth a, ProjectableMaybe (Projection cont), ProjectableFlattenMaybe (Maybe b) c)- => Projection cont (Maybe a) -- ^ Source 'Projection'. 'Maybe' phantom type- -> Pi a b -- ^ Projection path- -> Projection cont c -- ^ Narrower flatten and projected object.-(!??) = flattenPiMaybe----- | Interface to run recursively identity element laws.-class ProjectableRunIdsZip a b where- runIds :: ProjectableIdZip p => p a -> p b---- | Run left identity element law.-instance ProjectableRunIdsZip a b => ProjectableRunIdsZip ((), a) b where- runIds = runIds . leftId---- | Run right identity element law.-instance ProjectableRunIdsZip a b => ProjectableRunIdsZip (a, ()) b where- runIds = runIds . rightId---- | Base case definition to run recursively identity element laws.-instance ProjectableRunIdsZip a a where- runIds = id---- | Specialize 'runIds' for 'PlaceHolders' type.-flattenPh :: ProjectableRunIdsZip a b => PlaceHolders a -> PlaceHolders b-flattenPh = runIds---- -- | Binary operator the same as 'generalizedZip'.--- (>?<) :: (ProjectableIdZip p, ProjectableRunIdsZip (a, b) c)--- => p a -> p b -> p c--- (>?<) = generalizedZip'--infixl 8 !, ?!, ?!?, !??--- infixl 1 >?<
− src/Database/Relational/Query/Projection.hs
@@ -1,208 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.Projection--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines query projection type structure and interfaces.-module Database.Relational.Query.Projection (- -- * Projection data structure and interface- Projection,-- width,- columns,- untype,-- unsafeFromSqlTerms,- unsafeFromQualifiedSubQuery,- unsafeFromScalarSubQuery,- unsafeFromTable,-- unsafeStringSql,-- -- * Projections- pi, piMaybe, piMaybe',- wpi,-- flattenMaybe, just,-- unsafeToAggregated, unsafeToFlat, unsafeChangeContext,- unsafeStringSqlNotNullMaybe,-- pfmap, pap,-- -- * List Projection- 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.ProjectableClass- (ProductConstructor (..), ProjectableFunctor (..), ProjectableApplicative (..), )-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.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----- | Unsafely get SQL term from 'Proejction'.-unsafeStringSql :: Projection c r -> StringSQL-unsafeStringSql = unsafeProjectionStringSql---- | Get column SQL string list of projection.-columns :: Projection c r -- ^ Source 'Projection'- -> [StringSQL] -- ^ Result SQL string list-columns = projectionColumns---- | Width of 'Projection'.-width :: Projection c r -> Int-width = projectionWidth---- | Unsafely get untyped projection.-untype :: Projection c r -> UntypedProjection-untype = untypeProjection----- | Unsafely generate 'Projection' from qualified (joined) sub-query.-unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Projection c t-unsafeFromQualifiedSubQuery = typedProjection . untypedProjectionFromJoinedSubQuery---- | Unsafely generate 'Projection' from scalar sub-query.-unsafeFromScalarSubQuery :: SubQuery -> Projection c t-unsafeFromScalarSubQuery = Internal.projectFromScalarSubQuery---- | Unsafely generate unqualified 'Projection' from 'Table'.-unsafeFromTable :: Table r- -> Projection c r-unsafeFromTable = Internal.projectFromColumns . Table.columns---- | Unsafely generate 'Projection' from SQL expression strings.-unsafeFromSqlTerms :: [StringSQL] -> Projection c t-unsafeFromSqlTerms = Internal.projectFromColumns----- | Unsafely trace projection path.-unsafeProject :: PersistableRecordWidth a -> Projection c a' -> Pi a b -> Projection c b'-unsafeProject w p pi' =- Internal.projectFromColumns- . (UnsafePi.pi w pi')- . columns $ p---- | Trace projection path to get narrower 'Projection'.-wpi :: PersistableRecordWidth a- -> Projection c a -- ^ Source 'Projection'- -> Pi a b -- ^ Projection path- -> Projection c b -- ^ Narrower 'Projection'-wpi = unsafeProject---- | Trace projection path to get narrower 'Projection'.-pi :: PersistableWidth a- => Projection c a -- ^ Source 'Projection'- -> Pi a b -- ^ Projection path- -> Projection c b -- ^ Narrower 'Projection'-pi = unsafeProject persistableWidth---- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.-piMaybe :: PersistableWidth a- => Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type- -> Pi a b -- ^ Projection path- -> Projection c (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result-piMaybe = unsafeProject persistableWidth---- | Trace projection path to get narrower 'Projection'. From 'Maybe' type to 'Maybe' type.--- Leaf type of projection path is 'Maybe'.-piMaybe' :: PersistableWidth a- => Projection c (Maybe a) -- ^ Source 'Projection'. 'Maybe' type- -> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf- -> Projection c (Maybe b) -- ^ Narrower 'Projection'. 'Maybe' type result-piMaybe' = unsafeProject persistableWidth--unsafeCast :: Projection c r -> Projection c r'-unsafeCast = typedProjection . untypeProjection---- | Composite nested 'Maybe' on projection phantom type.-flattenMaybe :: Projection c (Maybe (Maybe a)) -> Projection c (Maybe a)-flattenMaybe = unsafeCast---- | Cast into 'Maybe' on projection phantom type.-just :: Projection c r -> Projection c (Maybe r)-just = unsafeCast---- | Unsafely cast context type tag.-unsafeChangeContext :: Projection c r -> Projection c' r-unsafeChangeContext = typedProjection . untypeProjection---- | Unsafely lift to aggregated context.-unsafeToAggregated :: Projection Flat r -> Projection Aggregated r-unsafeToAggregated = unsafeChangeContext---- | Unsafely down to flat context.-unsafeToFlat :: Projection Aggregated r -> Projection Flat r-unsafeToFlat = unsafeChangeContext--notNullMaybeConstraint :: HasColumnConstraint NotNull r => Projection c (Maybe r) -> NotNullColumnConstraint r-notNullMaybeConstraint = const KeyConstraint.columnConstraint---- | Unsafely get SQL string expression of not null key projection.-unsafeStringSqlNotNullMaybe :: HasColumnConstraint NotNull r => Projection c (Maybe r) -> StringSQL-unsafeStringSqlNotNullMaybe p = (!! KeyConstraint.index (notNullMaybeConstraint p)) . columns $ p---- | Projectable fmap of 'Projection' type.-pfmap :: ProductConstructor (a -> b)- => (a -> b) -> Projection c a -> Projection c b-_ `pfmap` p = unsafeCast p---- | Projectable ap of 'Projection' type.-pap :: Projection c (a -> b) -> Projection c a -> Projection c b-pf `pap` pa = typedProjection $ untypeProjection pf ++ untypeProjection pa---- | Compose seed of record type 'Projection'.-instance ProjectableFunctor (Projection c) where- (|$|) = pfmap---- | Compose record type 'Projection' using applicative style.-instance ProjectableApplicative (Projection c) where- (|*|) = pap---- | Projection type for row list.-data ListProjection p t = List [p t]- | Sub SubQuery---- | Make row list projection from 'Projection' list.-list :: [p t] -> ListProjection p t-list = List---- | Make row list projection from 'SubQuery'.-unsafeListFromSubQuery :: SubQuery -> ListProjection p t-unsafeListFromSubQuery = Sub---- | Map projection show operatoions and concatinate to single SQL expression.-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
− src/Database/Relational/Query/Pure.hs
@@ -1,162 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}-{-# LANGUAGE FlexibleInstances #-}---- |--- Module : Database.Relational.Query.Pure--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines interfaces between haskell pure values--- and query internal projection values.-module Database.Relational.Query.Pure () where--import Control.Applicative (pure)-import Data.Monoid ((<>))-import Data.Int (Int8, Int16, Int32, Int64)-import Data.ByteString (ByteString)-import qualified Data.ByteString.Lazy as LB-import Data.Text (Text)-import qualified Data.Text as T-import qualified Data.Text.Encoding as T-import qualified Data.Text.Lazy as LT-import qualified Data.Text.Lazy.Encoding as LT-import Text.Printf (PrintfArg, printf)-import Data.Time (FormatTime, Day, TimeOfDay, LocalTime, UTCTime, ZonedTime, formatTime)-import Data.Time.Locale.Compat (defaultTimeLocale)-import Data.DList (DList, fromList)--import Language.SQL.Keyword (Keyword (..))-import Database.Record- (PersistableWidth, persistableWidth, PersistableRecordWidth)-import Database.Record.Persistable- (runPersistableRecordWidth)--import Database.Relational.Query.Internal.SQL (StringSQL, stringSQL)--import Database.Relational.Query.ProjectableClass (ShowConstantTermsSQL (..))----- | Constant integral SQL terms.-intTermsSQL :: (Show a, Integral a) => a -> DList StringSQL-intTermsSQL = pure . stringSQL . show---- | Escape 'String' for constant SQL string expression.-escapeStringToSqlExpr :: String -> String-escapeStringToSqlExpr = rec where- rec "" = ""- rec ('\'':cs) = '\'' : '\'' : rec cs- rec (c:cs) = c : rec cs---- | From 'String' into constant SQL string expression.-stringExprSQL :: String -> StringSQL-stringExprSQL = stringSQL . ('\'':) . (++ "'") . escapeStringToSqlExpr--stringTermsSQL :: String -> DList StringSQL-stringTermsSQL = pure . stringExprSQL---- | Constant SQL terms of '()'.-instance ShowConstantTermsSQL ()---- | Constant SQL terms of 'Int8'.-instance ShowConstantTermsSQL Int8 where- showConstantTermsSQL' = intTermsSQL---- | Constant SQL terms of 'Int16'.-instance ShowConstantTermsSQL Int16 where- showConstantTermsSQL' = intTermsSQL---- | Constant SQL terms of 'Int32'.-instance ShowConstantTermsSQL Int32 where- showConstantTermsSQL' = intTermsSQL---- | Constant SQL terms of 'Int64'.-instance ShowConstantTermsSQL Int64 where- showConstantTermsSQL' = intTermsSQL---- | Constant SQL terms of 'Int'.--- Use this carefully, because this is architecture dependent size of integer type.-instance ShowConstantTermsSQL Int where- showConstantTermsSQL' = intTermsSQL---- | Constant SQL terms of 'String'.-instance ShowConstantTermsSQL String where- showConstantTermsSQL' = stringTermsSQL---- | Constant SQL terms of 'ByteString'.-instance ShowConstantTermsSQL ByteString where- showConstantTermsSQL' = stringTermsSQL . T.unpack . T.decodeUtf8---- | Constant SQL terms of 'LB.ByteString'.-instance ShowConstantTermsSQL LB.ByteString where- showConstantTermsSQL' = stringTermsSQL . LT.unpack . LT.decodeUtf8---- | Constant SQL terms of 'Text'.-instance ShowConstantTermsSQL Text where- showConstantTermsSQL' = stringTermsSQL . T.unpack---- | Constant SQL terms of 'LT.Text'.-instance ShowConstantTermsSQL LT.Text where- showConstantTermsSQL' = stringTermsSQL . LT.unpack---- | Constant SQL terms of 'Char'.-instance ShowConstantTermsSQL Char where- showConstantTermsSQL' = stringTermsSQL . (:"")---- | Constant SQL terms of 'Bool'.-instance ShowConstantTermsSQL Bool where- showConstantTermsSQL' = pure . stringSQL . d where- d True = "(0=0)"- d False = "(0=1)"--floatTerms :: (PrintfArg a, Ord a, Num a)=> a -> DList StringSQL-floatTerms f = pure . stringSQL $ printf fmt f where- fmt- | f >= 0 = "%f"- | otherwise = "(%f)"---- | Constant SQL terms of 'Float'. Caution for floating-point error rate.-instance ShowConstantTermsSQL Float where- showConstantTermsSQL' = floatTerms---- | Constant SQL terms of 'Double'. Caution for floating-point error rate.-instance ShowConstantTermsSQL Double where- showConstantTermsSQL' = floatTerms--constantTimeTerms :: FormatTime t => Keyword -> String -> t -> DList StringSQL-constantTimeTerms kw fmt t = pure $ kw <> stringExprSQL (formatTime defaultTimeLocale fmt t)---- | Constant SQL terms of 'Day'.-instance ShowConstantTermsSQL Day where- showConstantTermsSQL' = constantTimeTerms DATE "%Y-%m-%d"---- | Constant SQL terms of 'TimeOfDay'.-instance ShowConstantTermsSQL TimeOfDay where- showConstantTermsSQL' = constantTimeTerms TIME "%H:%M:%S"---- | Constant SQL terms of 'LocalTime'.-instance ShowConstantTermsSQL LocalTime where- showConstantTermsSQL' = constantTimeTerms TIMESTAMP "%Y-%m-%d %H:%M:%S"---- | Constant SQL terms of 'ZonedTime'.--- This generates ***NOT STANDARD*** SQL of TIMESTAMPTZ literal.-instance ShowConstantTermsSQL ZonedTime where- showConstantTermsSQL' = constantTimeTerms TIMESTAMPTZ "%Y-%m-%d %H:%M:%S%z"---- | Constant SQL terms of 'UTCTime'.--- This generates ***NOT STANDARD*** SQL of TIMESTAMPTZ literal with UTC timezone.-instance ShowConstantTermsSQL UTCTime where- showConstantTermsSQL' = constantTimeTerms TIMESTAMPTZ "%Y-%m-%d %H:%M:%S%z"--showMaybeTerms :: ShowConstantTermsSQL a => PersistableRecordWidth a -> Maybe a -> DList StringSQL-showMaybeTerms wa = d where- d (Just a) = showConstantTermsSQL' a- d Nothing = fromList . replicate (runPersistableRecordWidth wa) $ stringSQL "NULL"---- | Constant SQL terms of 'Maybe' type. Width inference is required.-instance (PersistableWidth a, ShowConstantTermsSQL a)- => ShowConstantTermsSQL (Maybe a) where- showConstantTermsSQL' = showMaybeTerms persistableWidth
− src/Database/Relational/Query/Relation.hs
@@ -1,387 +0,0 @@-{-# LANGUAGE FlexibleContexts #-}---- |--- Module : Database.Relational.Query.Relation--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines re-usable Relation type--- to compose complex query.-module Database.Relational.Query.Relation (- -- * Relation type- table, derivedRelation, tableOf,- relation, relation',- aggregateRelation, aggregateRelation',-- UniqueRelation,- unsafeUnique, unUnique,-- uniqueRelation', aggregatedUnique,-- -- * Query using relation- query, queryMaybe, queryList, queryList', queryScalar, queryScalar',- uniqueQuery', uniqueQueryMaybe',-- -- * Direct style join- JoinRestriction,- inner', left', right', full',- inner, left, right, full,- on',-- -- * Relation append- union, except, intersect,- unionAll, exceptAll, intersectAll,-- union', except', intersect',- unionAll', exceptAll', intersectAll',- ) where--import Control.Applicative ((<$>))--import Database.Relational.Query.Internal.BaseSQL (Duplication (Distinct, All))--import Database.Relational.Query.Context (Flat, Aggregated)-import Database.Relational.Query.Monad.BaseType- (ConfigureQuery, qualifyQuery,- Relation, unsafeTypeRelation, untypeRelation, relationWidth)-import Database.Relational.Query.Monad.Class- (MonadQualify (liftQualify), MonadQuery (query', queryMaybe'), on)-import Database.Relational.Query.Monad.Simple (QuerySimple, SimpleQuery)-import qualified Database.Relational.Query.Monad.Simple as Simple-import Database.Relational.Query.Monad.Aggregate (QueryAggregate, AggregatedQuery)-import qualified Database.Relational.Query.Monad.Aggregate as Aggregate-import Database.Relational.Query.Monad.Unique (QueryUnique, unsafeUniqueSubQuery)-import qualified Database.Relational.Query.Monad.Unique as Unique-import Database.Relational.Query.Table (Table, TableDerivable, derivedTable)-import Database.Relational.Query.Sub (SubQuery, NodeAttr(Just', Maybe))-import qualified Database.Relational.Query.Sub as SubQuery-import Database.Relational.Query.Scalar (ScalarDegree)-import Database.Relational.Query.Pi (Pi)-import Database.Relational.Query.Projection- (Projection, ListProjection)-import qualified Database.Relational.Query.Projection as Projection-import Database.Relational.Query.Projectable- (PlaceHolders, unitPlaceHolder, unsafeAddPlaceHolders, unsafePlaceHolders, projectZip)----- | Simple 'Relation' from 'Table'.-table :: Table r -> Relation () r-table = unsafeTypeRelation . return . SubQuery.fromTable---- | Inferred 'Relation'.-derivedRelation :: TableDerivable r => Relation () r-derivedRelation = table derivedTable---- | Interface to derive 'Table' type object.-tableOf :: TableDerivable r => Relation () r -> Table r-tableOf = const derivedTable--placeHoldersFromRelation :: Relation p r -> PlaceHolders p-placeHoldersFromRelation = const unsafePlaceHolders---- | Join sub-query. Query result is not 'Maybe'.-query :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation () r- -> m (Projection Flat r)-query = fmap snd . query'---- | Join sub-query. Query result is 'Maybe'.--- The combinations of 'query' and 'queryMaybe' express--- inner joins, left outer joins, right outer joins, and full outer joins.--- Here is an example of a right outer join:------ @--- outerJoin = relation $ do--- e <- queryMaybe employee--- d <- query department--- on $ e ?! E.deptId' .=. just (d ! D.deptId')--- return $ (,) |$| e |*| d--- @-queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m)- => Relation () r- -> m (Projection Flat (Maybe r))-queryMaybe = fmap snd . queryMaybe'--queryList0 :: MonadQualify ConfigureQuery m => Relation p r -> m (ListProjection (Projection c) r)-queryList0 = liftQualify- . fmap Projection.unsafeListFromSubQuery- . untypeRelation---- | List sub-query, for /IN/ and /EXIST/ with place-holder parameter 'p'.-queryList' :: MonadQualify ConfigureQuery m- => Relation p r- -> m (PlaceHolders p, ListProjection (Projection c) r)-queryList' rel = do- ql <- queryList0 rel- return (placeHoldersFromRelation rel, ql)---- | List sub-query, for /IN/ and /EXIST/.-queryList :: MonadQualify ConfigureQuery m- => Relation () r- -> m (ListProjection (Projection c) r)-queryList = queryList0--addUnitPH :: Functor f => f t -> f (PlaceHolders (), t)-addUnitPH = ((,) unitPlaceHolder <$>)---- | Finalize 'QuerySimple' monad and generate 'Relation' with place-holder parameter 'p'.-relation' :: SimpleQuery p r -> Relation p r-relation' = unsafeTypeRelation . Simple.toSubQuery---- | Finalize 'QuerySimple' monad and generate 'Relation'.-relation :: QuerySimple (Projection Flat r) -> Relation () r-relation = relation' . addUnitPH---- | Finalize 'QueryAggregate' monad and geneate 'Relation' with place-holder parameter 'p'.-aggregateRelation' :: AggregatedQuery p r -> Relation p r-aggregateRelation' = unsafeTypeRelation . Aggregate.toSubQuery---- | Finalize 'QueryAggregate' monad and geneate 'Relation'.-aggregateRelation :: QueryAggregate (Projection Aggregated r) -> Relation () r-aggregateRelation = aggregateRelation' . addUnitPH----- | Restriction predicate function type for direct style join operator,--- used on predicates of direct join style as follows.------ @--- do xy <- query $--- relX `inner` relY `on'` [ \x y -> ... ] -- this lambda form has JoinRestriction type--- ...--- @-type JoinRestriction a b = Projection Flat a -> Projection Flat b -> Projection Flat (Maybe Bool)---- | Basic direct join operation with place-holder parameters.-join' :: (qa -> QuerySimple (PlaceHolders pa, Projection Flat a))- -> (qb -> QuerySimple (PlaceHolders pb, Projection Flat b))- -> qa- -> qb- -> [JoinRestriction a b]- -> Relation (pa, pb) (a, b)-join' qL qR r0 r1 rs = relation' $ do- (ph0, pj0) <- qL r0- (ph1, pj1) <- qR r1- sequence_ [ on $ f pj0 pj1 | f <- rs ]- return (ph0 `projectZip` ph1, pj0 `projectZip` pj1)---- | Direct inner join with place-holder parameters.-inner' :: Relation pa a -- ^ Left query to join- -> Relation pb b -- ^ Right query to join- -> [JoinRestriction a b] -- ^ Join restrictions- -> Relation (pa, pb) (a, b) -- ^ Result joined relation-inner' = join' query' query'---- | Direct left outer join with place-holder parameters.-left' :: Relation pa a -- ^ Left query to join- -> Relation pb b -- ^ Right query to join- -> [JoinRestriction a (Maybe b)] -- ^ Join restrictions- -> Relation (pa, pb) (a, Maybe b) -- ^ Result joined relation-left' = join' query' queryMaybe'---- | Direct right outer join with place-holder parameters.-right' :: Relation pa a -- ^ Left query to join- -> Relation pb b -- ^ Right query to join- -> [JoinRestriction (Maybe a) b] -- ^ Join restrictions- -> Relation (pa, pb)(Maybe a, b) -- ^ Result joined relation-right' = join' queryMaybe' query'---- | Direct full outer join with place-holder parameters.-full' :: Relation pa a -- ^ Left query to join- -> Relation pb b -- ^ Right query to join- -> [JoinRestriction (Maybe a) (Maybe b)] -- ^ Join restrictions- -> Relation (pa, pb) (Maybe a, Maybe b) -- ^ Result joined relation-full' = join' queryMaybe' queryMaybe'---- | Basic direct join operation.-join_ :: (qa -> QuerySimple (Projection Flat a))- -> (qb -> QuerySimple (Projection Flat b))- -> qa- -> qb- -> [JoinRestriction a b]- -> Relation () (a, b)-join_ qL qR r0 r1 rs = relation $ do- pj0 <- qL r0- pj1 <- qR r1- sequence_ [ on $ f pj0 pj1 | f <- rs ]- return $ pj0 `projectZip` pj1---- | Direct inner join.-inner :: Relation () a -- ^ Left query to join- -> Relation () b -- ^ Right query to join- -> [JoinRestriction a b] -- ^ Join restrictions- -> Relation () (a, b) -- ^ Result joined relation-inner = join_ query query---- | Direct left outer join.-left :: Relation () a -- ^ Left query to join- -> Relation () b -- ^ Right query to join- -> [JoinRestriction a (Maybe b)] -- ^ Join restrictions- -> Relation () (a, Maybe b) -- ^ Result joined relation-left = join_ query queryMaybe---- | Direct right outer join.-right :: Relation () a -- ^ Left query to join- -> Relation () b -- ^ Right query to join- -> [JoinRestriction (Maybe a) b] -- ^ Join restrictions- -> Relation () (Maybe a, b) -- ^ Result joined relation-right = join_ queryMaybe query---- | Direct full outer join.-full :: Relation () a -- ^ Left query to join- -> Relation () b -- ^ Right query to join- -> [JoinRestriction (Maybe a) (Maybe b)] -- ^ Join restrictions- -> Relation () (Maybe a, Maybe b) -- ^ Result joined relation-full = join_ queryMaybe queryMaybe---- | Apply restriction for direct join style.-on' :: ([JoinRestriction a b] -> Relation pc (a, b))- -> [JoinRestriction a b]- -> Relation pc (a, b)-on' = ($)--infixl 8 `inner'`, `left'`, `right'`, `full'`, `inner`, `left`, `right`, `full`, `on'`--unsafeLiftAppend :: (SubQuery -> SubQuery -> SubQuery)- -> Relation p a- -> Relation q a- -> Relation r a-unsafeLiftAppend op a0 a1 = unsafeTypeRelation $ do- s0 <- untypeRelation a0- s1 <- untypeRelation a1- return $ s0 `op` s1--liftAppend :: (SubQuery -> SubQuery -> SubQuery)- -> Relation () a- -> Relation () a- -> Relation () a-liftAppend = unsafeLiftAppend---- | Union of two relations.-union :: Relation () a -> Relation () a -> Relation () a-union = liftAppend $ SubQuery.union Distinct---- | Union of two relations. Not distinct.-unionAll :: Relation () a -> Relation () a -> Relation () a-unionAll = liftAppend $ SubQuery.union All---- | Subtraction of two relations.-except :: Relation () a -> Relation () a -> Relation () a-except = liftAppend $ SubQuery.except Distinct---- | Subtraction of two relations. Not distinct.-exceptAll :: Relation () a -> Relation () a -> Relation () a-exceptAll = liftAppend $ SubQuery.except All---- | Intersection of two relations.-intersect :: Relation () a -> Relation () a -> Relation () a-intersect = liftAppend $ SubQuery.intersect Distinct---- | Intersection of two relations. Not distinct.-intersectAll :: Relation () a -> Relation () a -> Relation () a-intersectAll = liftAppend $ SubQuery.intersect All--liftAppend' :: (SubQuery -> SubQuery -> SubQuery)- -> Relation p a- -> Relation q a- -> Relation (p, q) a-liftAppend' = unsafeLiftAppend---- | Union of two relations with place-holder parameters.-union' :: Relation p a -> Relation q a -> Relation (p, q) a-union' = liftAppend' $ SubQuery.union Distinct---- | Union of two relations with place-holder parameters. Not distinct.-unionAll' :: Relation p a -> Relation q a -> Relation (p, q) a-unionAll' = liftAppend' $ SubQuery.union All---- | Subtraction of two relations with place-holder parameters.-except' :: Relation p a -> Relation q a -> Relation (p, q) a-except' = liftAppend' $ SubQuery.except Distinct---- | Subtraction of two relations with place-holder parameters. Not distinct.-exceptAll' :: Relation p a -> Relation q a -> Relation (p, q) a-exceptAll' = liftAppend' $ SubQuery.except All---- | Intersection of two relations with place-holder parameters.-intersect' :: Relation p a -> Relation q a -> Relation (p, q) a-intersect' = liftAppend' $ SubQuery.intersect Distinct---- | Intersection of two relations with place-holder parameters. Not distinct.-intersectAll' :: Relation p a -> Relation q a -> Relation (p, q) a-intersectAll' = liftAppend' $ SubQuery.intersect All--infixl 7 `union`, `except`, `unionAll`, `exceptAll`-infixl 8 `intersect`, `intersectAll`-infixl 7 `union'`, `except'`, `unionAll'`, `exceptAll'`-infixl 8 `intersect'`, `intersectAll'`--{---- | Get projection width from 'Relation'.-width :: Relation p r -> Int-width = SubQuery.width . subQueryFromRelation--}---- | Unique relation type to compose scalar queries.-newtype UniqueRelation p c r = Unique (Relation p r)---- | Unsafely specify unique relation.-unsafeUnique :: Relation p r -> UniqueRelation p c r-unsafeUnique = Unique---- | Discard unique attribute.-unUnique :: UniqueRelation p c r -> Relation p r-unUnique (Unique r) = r---- | Basic monadic join operation using 'MonadQuery'.-uniqueQueryWithAttr :: NodeAttr- -> UniqueRelation p c r- -> QueryUnique (PlaceHolders p, Projection c r)-uniqueQueryWithAttr attr = unsafeAddPlaceHolders . run where- run rel = do- q <- liftQualify $ do- sq <- untypeRelation (unUnique rel)- qualifyQuery sq- Projection.unsafeChangeContext <$> unsafeUniqueSubQuery attr q---- | Join unique sub-query with place-holder parameter 'p'.-uniqueQuery' :: UniqueRelation p c r- -> QueryUnique (PlaceHolders p, Projection c r)-uniqueQuery' = uniqueQueryWithAttr Just'---- | Join unique sub-query with place-holder parameter 'p'. Query result is 'Maybe'.-uniqueQueryMaybe' :: UniqueRelation p c r- -> QueryUnique (PlaceHolders p, Projection c (Maybe r))-uniqueQueryMaybe' pr = do- (ph, pj) <- uniqueQueryWithAttr Maybe pr- return (ph, Projection.just pj)---- | Finalize 'QueryUnique' monad and generate 'UniqueRelation'.-uniqueRelation' :: QueryUnique (PlaceHolders p, Projection c r) -> UniqueRelation p c r-uniqueRelation' = unsafeUnique . unsafeTypeRelation . Unique.toSubQuery---- | Aggregated 'UniqueRelation'.-aggregatedUnique :: Relation ph r- -> Pi r a- -> (Projection Flat a -> Projection Aggregated b)- -> UniqueRelation ph Flat b-aggregatedUnique rel k ag = unsafeUnique . aggregateRelation' $ do- (ph, a) <- query' rel- return (ph, ag $ Projection.wpi (relationWidth rel) a k)---- | Scalar sub-query with place-holder parameter 'p'.-queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => UniqueRelation p c r- -> m (PlaceHolders p, Projection c (Maybe r))-queryScalar' ur =- unsafeAddPlaceHolders . liftQualify $- Projection.unsafeFromScalarSubQuery <$> untypeRelation (unUnique ur)---- | Scalar sub-query.-queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)- => UniqueRelation () c r- -> m (Projection c (Maybe r))-queryScalar = fmap snd . queryScalar'
− src/Database/Relational/Query/SQL.hs
@@ -1,118 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- Module : Database.Relational.Query.SQL--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines functions to generate simple SQL strings.-module Database.Relational.Query.SQL (- -- * Query suffix- QuerySuffix, showsQuerySuffix,-- -- * Update SQL- updatePrefixSQL,- updateSQL',- updateOtherThanKeySQL', updateOtherThanKeySQL,-- -- * Insert SQL- insertPrefixSQL, insertSQL,-- -- * Delete SQL- deletePrefixSQL', deletePrefixSQL- ) where--import Data.Array (listArray, (!))-import Data.Monoid (mconcat, (<>))--import Language.SQL.Keyword (Keyword(..), (.=.), (|*|))-import qualified Language.SQL.Keyword as SQL-import Database.Record (PersistableWidth)-import Database.Record.ToSql (untypedUpdateValuesIndex)--import Database.Relational.Query.Internal.SQL- (StringSQL, stringSQL, showStringSQL, rowConsStringSQL, )--import Database.Relational.Query.Pi (Pi)-import qualified Database.Relational.Query.Pi.Unsafe as UnsafePi-import Database.Relational.Query.Table (Table, name, columns, recordWidth)-import qualified Database.Relational.Query.Projection as Projection----- | Type for query suffix words-type QuerySuffix = [Keyword]---- | Expand query suffix words-showsQuerySuffix :: QuerySuffix -> StringSQL-showsQuerySuffix = mconcat---- | Generate prefix string of update SQL.-updatePrefixSQL :: Table r -> StringSQL-updatePrefixSQL table = UPDATE <> stringSQL (name table)---- | Generate update SQL by specified key and table.--- Columns name list of table are also required.-updateSQL' :: String -- ^ Table name- -> [StringSQL] -- ^ Column name list to update- -> [StringSQL] -- ^ Key column name list- -> String -- ^ Result SQL-updateSQL' table cols key =- showStringSQL $ mconcat- [UPDATE, stringSQL table, SET, SQL.fold (|*|) updAssigns,- WHERE, SQL.fold SQL.and keyAssigns]- where- assigns cs = [ c .=. "?" | c <- cs ]- updAssigns = assigns cols- keyAssigns = assigns key---- | Generate update SQL by specified key and table.--- Columns name list of table are also required.-updateOtherThanKeySQL' :: String -- ^ Table name- -> [StringSQL] -- ^ Column name list- -> [Int] -- ^ Key column indexes- -> String -- ^ Result SQL-updateOtherThanKeySQL' table cols ixs =- updateSQL' table updColumns keyColumns- where- width' = length cols- cols' = listArray (0, width' -1) cols- otherThanKey = untypedUpdateValuesIndex ixs width'- columns' is = [ cols' ! i | i <- is ]- updColumns = columns' otherThanKey- keyColumns = columns' ixs---- | Generate update SQL specified by single key.-updateOtherThanKeySQL :: Table r -- ^ Table metadata- -> Pi r p -- ^ Key columns- -> String -- ^ Result SQL-updateOtherThanKeySQL tbl key =- updateOtherThanKeySQL' (name tbl) (columns tbl) (UnsafePi.unsafeExpandIndexes' (recordWidth tbl) key)---- | Generate prefix string of insert SQL.-insertPrefixSQL :: Pi r r' -> Table r -> StringSQL-insertPrefixSQL pi' table =- INSERT <> INTO <> stringSQL (name table) <> rowConsStringSQL cols where- cols = Projection.columns . Projection.wpi (recordWidth table) (Projection.unsafeFromTable table) $ pi'--{-# DEPRECATED insertSQL "Deprecated." #-}--- | Generate insert SQL.-insertSQL :: PersistableWidth r- => Pi r r' -- ^ Columns selector to insert- -> Table r -- ^ Table metadata- -> String -- ^ Result SQL-insertSQL pi' tbl = showStringSQL $ insertPrefixSQL pi' tbl <> VALUES <> vs where- w = UnsafePi.width pi'- vs = rowConsStringSQL (replicate w "?")---- | Generate all column delete SQL by specified table. Untyped table version.-deletePrefixSQL' :: String -> StringSQL-deletePrefixSQL' table = DELETE <> FROM <> stringSQL table---- | Generate all column delete SQL by specified table.-deletePrefixSQL :: Table r -- ^ Table metadata- -> StringSQL -- ^ Result SQL-deletePrefixSQL = deletePrefixSQL' . name
− src/Database/Relational/Query/Scalar.hs
@@ -1,32 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleInstances #-}---- |--- Module : Database.Relational.Query.Scalar--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines type classes and templates for scalar queries.-module Database.Relational.Query.Scalar (- -- * Single degree constraint- ScalarDegree, defineScalarDegree- ) where--import Language.Haskell.TH (Q, TypeQ, Dec)--import Database.Record (PersistableWidth)----- | Constraint which represents scalar degree.-class PersistableWidth ct => ScalarDegree ct--instance ScalarDegree ct => ScalarDegree (Maybe ct)---- | 'ScalarDegree' instance templates.-defineScalarDegree :: TypeQ -> Q [Dec]-defineScalarDegree typeCon = do- [d| instance ScalarDegree $(typeCon) |]
− src/Database/Relational/Query/Sub.hs
@@ -1,329 +0,0 @@-{-# LANGUAGE OverloadedStrings #-}---- |--- Module : Database.Relational.Query.Sub--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines sub-query structure used in query products.-module Database.Relational.Query.Sub (- -- * Sub-query- SubQuery, fromTable, flatSubQuery, aggregatedSubQuery,- union, except, intersect,- showSQL, toSQL, unitSQL, width,-- -- * Qualified Sub-query- Qualifier (Qualifier),- Qualified,- queryWidth,-- -- * Sub-query columns- column,-- -- * Projection- Projection, ProjectionUnit, UntypedProjection,-- untypedProjectionFromJoinedSubQuery,-- projectionColumns, unsafeProjectionStringSql,-- -- * Product of sub-queries- JoinProduct, NodeAttr (..),- ProductBuilder,-- -- * Query restriction- QueryRestriction,- composeWhere, composeHaving- ) where--import Control.Applicative ((<$>))-import Data.Monoid (mempty, (<>), mconcat)-import Data.Traversable (traverse)--import Language.SQL.Keyword (Keyword(..), (|*|))-import qualified Language.SQL.Keyword as SQL--import Database.Relational.Query.Internal.Config- (Config (productUnitSupport), ProductUnitSupport (PUSupported, PUNotSupported))-import qualified Database.Relational.Query.Context as Context-import Database.Relational.Query.Internal.SQL- (StringSQL, stringSQL, rowStringSQL, showStringSQL, )-import Database.Relational.Query.Internal.BaseSQL- (Duplication (..), showsDuplication, OrderingTerm, composeOrderBy, )-import Database.Relational.Query.Internal.GroupingSQL- (AggregateElem, composeGroupBy, )-import Database.Relational.Query.Internal.Sub- (SubQuery (..), Projection,- CaseClause(..), WhenClauses (..),- UntypedProjection, ProjectionUnit (..),- JoinProduct, QueryProductTree, ProductBuilder,- NodeAttr (Just', Maybe), ProductTree (Leaf, Join),- SetOp (..), BinOp (..), Qualifier (..), Qualified (..),- QueryRestriction)-import qualified Database.Relational.Query.Internal.Sub as Internal-import Database.Relational.Query.Internal.UntypedTable ((!))-import qualified Database.Relational.Query.Internal.UntypedTable as UntypedTable--import Database.Relational.Query.Table (Table)-import qualified Database.Relational.Query.Table as Table-import Database.Relational.Query.ProjectableClass (showConstantTermsSQL)-import Database.Relational.Query.Pure ()---showsSetOp' :: SetOp -> StringSQL-showsSetOp' = d where- d Union = UNION- d Except = EXCEPT- d Intersect = INTERSECT--showsSetOp :: SetOp -> Duplication -> StringSQL-showsSetOp op dup0 = showsSetOp' op <> mayDup dup0 where- mayDup dup@All = showsDuplication dup- mayDup Distinct = mempty---- | 'SubQuery' from 'Table'.-fromTable :: Table r -- ^ Typed 'Table' metadata- -> SubQuery -- ^ Result 'SubQuery'-fromTable = Table . Table.unType---- | Unsafely generate flat 'SubQuery' from untyped components.-flatSubQuery :: Config- -> UntypedProjection- -> Duplication- -> JoinProduct- -> QueryRestriction Context.Flat- -> [OrderingTerm]- -> SubQuery-flatSubQuery = Flat---- | Unsafely generate aggregated 'SubQuery' from untyped components.-aggregatedSubQuery :: Config- -> UntypedProjection- -> Duplication- -> JoinProduct- -> QueryRestriction Context.Flat- -> [AggregateElem]- -> QueryRestriction Context.Aggregated- -> [OrderingTerm]- -> SubQuery-aggregatedSubQuery = Aggregated--setBin :: SetOp -> Duplication -> SubQuery -> SubQuery -> SubQuery-setBin op = Bin . BinOp . (,) op---- | Union binary operator on 'SubQuery'-union :: Duplication -> SubQuery -> SubQuery -> SubQuery-union = setBin Union---- | Except binary operator on 'SubQuery'-except :: Duplication -> SubQuery -> SubQuery -> SubQuery-except = setBin Except---- | Intersect binary operator on 'SubQuery'-intersect :: Duplication -> SubQuery -> SubQuery -> SubQuery-intersect = setBin Intersect---- | Width of 'SubQuery'.-width :: SubQuery -> Int-width = d where- d (Table u) = UntypedTable.width' u- d (Bin _ l _) = width l- d (Flat _ up _ _ _ _) = Internal.untypedProjectionWidth up- d (Aggregated _ up _ _ _ _ _ _) = Internal.untypedProjectionWidth up---- | SQL to query table.-fromTableToSQL :: UntypedTable.Untyped -> StringSQL-fromTableToSQL t =- SELECT <> SQL.fold (|*|) (UntypedTable.columns' t) <>- FROM <> stringSQL (UntypedTable.name' t)---- | Generate normalized column SQL from table.-fromTableToNormalizedSQL :: UntypedTable.Untyped -> StringSQL-fromTableToNormalizedSQL t = SELECT <> SQL.fold (|*|) columns' <>- FROM <> stringSQL (UntypedTable.name' t) where- columns' = zipWith asColumnN- (UntypedTable.columns' t)- [(0 :: Int)..]---- | Normalized column SQL-normalizedSQL :: SubQuery -> StringSQL-normalizedSQL = d where- d (Table t) = fromTableToNormalizedSQL t- d sub@(Bin {}) = showUnitSQL sub- d sub@(Flat _ _ _ _ _ ots)- | null ots = showSQL sub- | otherwise = showUnitSQL sub- d sub@(Aggregated _ _ _ _ _ _ _ ots)- | null ots = showSQL sub- | otherwise = showUnitSQL sub--selectPrefixSQL :: UntypedProjection -> Duplication -> StringSQL-selectPrefixSQL up da = SELECT <> showsDuplication da <>- SQL.fold (|*|) columns' where- columns' = zipWith asColumnN- (map columnOfProjectionUnit up)- [(0 :: Int)..]---- | SQL string for nested-query and toplevel-SQL.-toSQLs :: SubQuery- -> (StringSQL, StringSQL) -- ^ sub-query SQL and top-level SQL-toSQLs = d where- d (Table u) = (stringSQL $ UntypedTable.name' u, fromTableToSQL u)- d (Bin (BinOp (op, da)) l r) = (SQL.paren q, q) where- q = mconcat [normalizedSQL l, showsSetOp op da, normalizedSQL r]- d (Flat cf up da pd rs od) = (SQL.paren q, q) where- q = selectPrefixSQL up da <> showsJoinProduct (productUnitSupport cf) pd <> composeWhere rs- <> composeOrderBy od- d (Aggregated cf up da pd rs ag grs od) = (SQL.paren q, q) where- q = selectPrefixSQL up da <> showsJoinProduct (productUnitSupport cf) pd <> composeWhere rs- <> composeGroupBy ag <> composeHaving grs <> composeOrderBy od--showUnitSQL :: SubQuery -> StringSQL-showUnitSQL = fst . toSQLs---- | SQL string for nested-qeury.-unitSQL :: SubQuery -> String-unitSQL = showStringSQL . showUnitSQL---- | SQL StringSQL for toplevel-SQL.-showSQL :: SubQuery -> StringSQL-showSQL = snd . toSQLs---- | SQL string for toplevel-SQL.-toSQL :: SubQuery -> String-toSQL = showStringSQL . showSQL--columnN :: Int -> StringSQL-columnN i = stringSQL $ 'f' : show i--asColumnN :: StringSQL -> Int -> StringSQL-c `asColumnN` n =c `SQL.as` columnN n---- | Alias string from qualifier-showQualifier :: Qualifier -> StringSQL-showQualifier (Qualifier i) = stringSQL $ 'T' : show i---- | Binary operator to qualify.-(<.>) :: Qualifier -> StringSQL -> StringSQL-i <.> n = showQualifier i SQL.<.> n---- | Qualified expression from qualifier and projection index.-columnFromId :: Qualifier -> Int -> StringSQL-columnFromId qi i = qi <.> columnN i---- | From 'Qualified' SQL string into qualified formed 'String'--- like (SELECT ...) AS T<n>-qualifiedSQLas :: Qualified StringSQL -> StringSQL-qualifiedSQLas q = Internal.unQualify q <> showQualifier (Internal.qualifier q)---- | Width of 'Qualified' 'SubQUery'.-queryWidth :: Qualified SubQuery -> Int-queryWidth = width . Internal.unQualify---- | Get column SQL string of 'SubQuery'.-column :: Qualified SubQuery -> Int -> StringSQL-column qs = d (Internal.unQualify qs) where- q = Internal.qualifier qs- d (Table u) i = q <.> (u ! i)- d (Bin {}) i = q `columnFromId` i- d (Flat _ up _ _ _ _) i = columnOfUntypedProjection up i- d (Aggregated _ up _ _ _ _ _ _) i = columnOfUntypedProjection up i----- | Make untyped projection from joined sub-query.-untypedProjectionFromJoinedSubQuery :: Qualified SubQuery -> UntypedProjection-untypedProjectionFromJoinedSubQuery qs = d $ Internal.unQualify qs where- normalized = SubQueryRef <$> traverse (\q -> [0 .. width q - 1]) qs- d (Table _) = map RawColumn . map (column qs)- $ take (queryWidth qs) [0..]- d (Bin {}) = normalized- d (Flat {}) = normalized- d (Aggregated {}) = normalized---- | index result of each when clause and else clause.-indexWhensClause :: WhenClauses -> Int -> StringSQL-indexWhensClause (WhenClauses ps e) i =- mconcat [ when' p r | (p, r) <- ps] <> else' <> SQL.END- where- when' p r = SQL.WHEN <> rowStringSQL (map columnOfProjectionUnit p) <>- SQL.THEN <> columnOfUntypedProjection r i- else' = SQL.ELSE <> columnOfUntypedProjection e i---- | index result of each when clause and else clause.-caseClause :: CaseClause -> Int -> StringSQL-caseClause c i = d c where- d (CaseSearch wcl) = SQL.CASE <> indexWhensClause wcl i- d (CaseSimple m wcl) = SQL.CASE <> rowStringSQL (map columnOfProjectionUnit m) <> indexWhensClause wcl i---- | Convert from ProjectionUnit into column.-columnOfProjectionUnit :: ProjectionUnit -> StringSQL-columnOfProjectionUnit = d where- d (RawColumn e) = e- d (SubQueryRef qi) = Internal.qualifier qi `columnFromId` Internal.unQualify qi- d (Scalar sub) = showUnitSQL sub- d (Case c i) = caseClause c i---- | Get column SQL string of 'UntypedProjection'.-columnOfUntypedProjection :: UntypedProjection -- ^ Source 'Projection'- -> Int -- ^ Column index- -> StringSQL -- ^ Result SQL string-columnOfUntypedProjection up i- | 0 <= i && i < Internal.untypedProjectionWidth up =- columnOfProjectionUnit $ up !! i- | otherwise =- error $ "columnOfUntypedProjection: index out of bounds: " ++ show i---- | Get column SQL string list of projection.-projectionColumns :: Projection c r -- ^ Source 'Projection'- -> [StringSQL] -- ^ Result SQL string list-projectionColumns = map columnOfProjectionUnit . Internal.untypeProjection---- | Unsafely get SQL term from 'Proejction'.-unsafeProjectionStringSql :: Projection c r -> StringSQL-unsafeProjectionStringSql = rowStringSQL . projectionColumns----- | Show product tree of query into SQL. StringSQL result.-showsQueryProduct :: QueryProductTree -> StringSQL-showsQueryProduct = rec where- joinType Just' Just' = INNER- joinType Just' Maybe = LEFT- joinType Maybe Just' = RIGHT- joinType Maybe Maybe = FULL- urec n = case Internal.nodeTree n of- p@(Leaf _) -> rec p- p@(Join {}) -> SQL.paren (rec p)- rec (Leaf q) = qualifiedSQLas $ fmap showUnitSQL q- rec (Join left' right' rs) =- mconcat- [urec left',- joinType (Internal.nodeAttr left') (Internal.nodeAttr right'), JOIN,- urec right',- ON, foldr1 SQL.and $ ps ++ concat [ showConstantTermsSQL True | null ps ] ]- where ps = [ unsafeProjectionStringSql p | p <- rs ]---- | Shows join product of query.-showsJoinProduct :: ProductUnitSupport -> JoinProduct -> StringSQL-showsJoinProduct ups = maybe (up ups) from where- from qp = FROM <> showsQueryProduct qp- up PUSupported = mempty- up PUNotSupported = error "relation: Unit product support mode is disabled!"----- | Compose SQL String from 'QueryRestriction'.-composeRestrict :: Keyword -> QueryRestriction c -> StringSQL-composeRestrict k = d where- d [] = mempty- d ps@(_:_) = k <> foldr1 SQL.and [ unsafeProjectionStringSql p | p <- ps ]---- | Compose WHERE clause from 'QueryRestriction'.-composeWhere :: QueryRestriction Context.Flat -> StringSQL-composeWhere = composeRestrict WHERE---- | Compose HAVING clause from 'QueryRestriction'.-composeHaving :: QueryRestriction Context.Aggregated -> StringSQL-composeHaving = composeRestrict HAVING
− src/Database/Relational/Query/TH.hs
@@ -1,464 +0,0 @@-{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE MultiParamTypeClasses #-}-{-# LANGUAGE ExplicitForAll #-}-{-# LANGUAGE ParallelListComp #-}---- |--- Module : Database.Relational.Query.TH--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines templates for Haskell record type and type class instances--- to define column projection on SQL query like Haskell records.--- Templates are generated by also using functions of "Database.Record.TH" module,--- so mapping between list of untyped SQL type and Haskell record type will be done too.-module Database.Relational.Query.TH (- -- * All templates about table- defineTable,-- -- * Inlining typed 'Query'- unsafeInlineQuery,- inlineQuery,-- -- * Column projections and basic 'Relation' for Haskell record- defineTableTypesAndRecord,-- -- * Constraint key templates- defineHasPrimaryKeyInstance,- defineHasPrimaryKeyInstanceWithConfig,- defineHasNotNullKeyInstance,- defineHasNotNullKeyInstanceWithConfig,- defineScalarDegree,-- -- * Column projections- defineColumns, defineColumnsDefault,-- defineTuplePi,-- -- * Table metadata type and basic 'Relation'- defineTableTypes, defineTableTypesWithConfig,-- -- * Basic SQL templates generate rules- definePrimaryQuery,- definePrimaryUpdate,-- -- * Var expression templates- derivationExpDefault,- tableVarExpDefault,- relationVarExp,-- -- * Derived SQL templates from table definitions- defineSqlsWithPrimaryKey,- defineSqlsWithPrimaryKeyDefault,-- -- * Add type class instance against record type- defineProductConstructorInstance,-- -- * Reify- makeRelationalRecordDefault,- reifyRelation,- ) where--import Data.Char (toUpper, toLower)-import Data.List (foldl1')-import Data.Array.IArray ((!))--import Language.Haskell.TH- (Name, nameBase, Q, reify, TypeQ, Type (AppT, ConT), ExpQ,- tupleT, appT, Dec, stringE, listE)-import Language.Haskell.TH.Compat.Reify (unVarI)-import Language.Haskell.TH.Name.CamelCase- (VarName, varName, ConName (ConName), conName, varNameWithPrefix, varCamelcaseName, toVarExp, toTypeCon)-import Language.Haskell.TH.Lib.Extra (simpleValD, maybeD, integralE)--import Database.Record.TH- (columnOffsetsVarNameDefault, recordTypeName, recordTemplate,- defineRecordTypeWithConfig, defineHasColumnConstraintInstance)-import qualified Database.Record.TH as Record--import Database.Relational.Query- (Table, Pi, id', Relation, ShowConstantTermsSQL,- NameConfig (..), SchemaNameMode (..), IdentifierQuotation (..),- Config (normalizedTableName, schemaNameMode, nameConfig, identifierQuotation),- relationalQuerySQL, Query, relationalQuery, KeyUpdate,- Insert, derivedInsert, InsertQuery, derivedInsertQuery,- HasConstraintKey(constraintKey), Primary, NotNull, primary, primaryUpdate)--import Database.Relational.Query.BaseTH (defineProductConstructorInstance, defineTuplePi)-import Database.Relational.Query.Scalar (defineScalarDegree)-import Database.Relational.Query.Constraint (Key, unsafeDefineConstraintKey)-import Database.Relational.Query.Table (TableDerivable (..))-import qualified Database.Relational.Query.Table as Table-import Database.Relational.Query.Relation (derivedRelation)-import Database.Relational.Query.SQL (QuerySuffix)-import Database.Relational.Query.Type (unsafeTypedQuery)-import qualified Database.Relational.Query.Pi.Unsafe as UnsafePi----- | Rule template to infer constraint key.-defineHasConstraintKeyInstance :: TypeQ -- ^ Constraint type- -> TypeQ -- ^ Record type- -> TypeQ -- ^ Key type- -> [Int] -- ^ Indexes specifies key- -> Q [Dec] -- ^ Result 'HasConstraintKey' declaration-defineHasConstraintKeyInstance constraint recType colType indexes = do- -- kc <- defineHasColumnConstraintInstance constraint recType index- ck <- [d| instance HasConstraintKey $constraint $recType $colType where- constraintKey = unsafeDefineConstraintKey $(listE [integralE ix | ix <- indexes])- |]- return ck---- | Rule template to infer primary key.-defineHasPrimaryKeyInstance :: TypeQ -- ^ Record type- -> TypeQ -- ^ Key type- -> [Int] -- ^ Indexes specifies key- -> Q [Dec] -- ^ Result constraint key declarations-defineHasPrimaryKeyInstance recType colType indexes = do- kc <- Record.defineHasPrimaryKeyInstance recType indexes- ck <- defineHasConstraintKeyInstance [t| Primary |] recType colType indexes- return $ kc ++ ck---- | Rule template to infer primary key.-defineHasPrimaryKeyInstanceWithConfig :: Config -- ^ configuration parameters- -> String -- ^ Schema name- -> String -- ^ Table name- -> TypeQ -- ^ Column type- -> [Int] -- ^ Primary key index- -> Q [Dec] -- ^ Declarations of primary constraint key-defineHasPrimaryKeyInstanceWithConfig config scm =- defineHasPrimaryKeyInstance . fst . recordTemplate (recordConfig $ nameConfig config) scm---- | Rule template to infer not-null key.-defineHasNotNullKeyInstance :: TypeQ -- ^ Record type- -> Int -- ^ Column index- -> Q [Dec] -- ^ Result 'ColumnConstraint' declaration-defineHasNotNullKeyInstance =- defineHasColumnConstraintInstance [t| NotNull |]---- | Rule template to infer not-null key.-defineHasNotNullKeyInstanceWithConfig :: Config -- ^ configuration parameters- -> String -- ^ Schema name- -> String -- ^ Table name- -> Int -- ^ NotNull key index- -> Q [Dec] -- ^ Declaration of not-null constraint key-defineHasNotNullKeyInstanceWithConfig config scm =- defineHasNotNullKeyInstance . fst . recordTemplate (recordConfig $ nameConfig config) scm----- | Column projection path 'Pi' template.-columnTemplate' :: TypeQ -- ^ Record type- -> VarName -- ^ Column declaration variable name- -> ExpQ -- ^ Column index expression in record (begin with 0)- -> TypeQ -- ^ Column type- -> Q [Dec] -- ^ Column projection path declaration-columnTemplate' recType var' iExp colType = do- let var = varName var'- simpleValD var [t| Pi $recType $colType |]- [| UnsafePi.definePi $(iExp) |]---- | Column projection path 'Pi' and constraint key template.-columnTemplate :: Maybe (TypeQ, VarName) -- ^ May Constraint type and constraint object name- -> TypeQ -- ^ Record type- -> VarName -- ^ Column declaration variable name- -> ExpQ -- ^ Column index expression in record (begin with 0)- -> TypeQ -- ^ Column type- -> Q [Dec] -- ^ Column projection path declaration-columnTemplate mayConstraint recType var' iExp colType = do- col <- columnTemplate' recType var' iExp colType- cr <- maybe- (return [])- ( \(constraint, cname') -> do- simpleValD (varName cname') [t| Key $constraint $recType $colType |]- [| unsafeDefineConstraintKey $(iExp) |] )- mayConstraint- return $ col ++ cr---- | Column projection path 'Pi' templates.-defineColumns :: ConName -- ^ Record type name- -> [((VarName, TypeQ), Maybe (TypeQ, VarName))] -- ^ Column info list- -> Q [Dec] -- ^ Column projection path declarations-defineColumns recTypeName cols = do- let defC ((cn, ct), mayCon) ix = columnTemplate mayCon (toTypeCon recTypeName) cn- [| $(toVarExp . columnOffsetsVarNameDefault $ conName recTypeName) ! $(integralE ix) |] ct- fmap concat . sequence $ zipWith defC cols [0 :: Int ..]---- | Make column projection path and constraint key templates using default naming rule.-defineColumnsDefault :: ConName -- ^ Record type name- -> [((String, TypeQ), Maybe TypeQ)] -- ^ Column info list- -> Q [Dec] -- ^ Column projection path declarations-defineColumnsDefault recTypeName cols =- defineColumns recTypeName [((varN n, ct), fmap (withCName n) mayC) | ((n, ct), mayC) <- cols]- where varN name = varCamelcaseName (name ++ "'")- withCName name t = (t, varCamelcaseName ("constraint_key_" ++ name))---- | Rule template to infer table derivations.-defineTableDerivableInstance :: TypeQ -> String -> [String] -> Q [Dec]-defineTableDerivableInstance recordType' table columns =- [d| instance TableDerivable $recordType' where- derivedTable = Table.table $(stringE table) $(listE $ map stringE columns)- |]---- | Template to define inferred entries from table type.-defineTableDerivations :: VarName -- ^ Table declaration variable name- -> VarName -- ^ Relation declaration variable name- -> VarName -- ^ Insert statement declaration variable name- -> VarName -- ^ InsertQuery statement declaration variable name- -> TypeQ -- ^ Record type- -> Q [Dec] -- ^ Table and Relation declaration-defineTableDerivations tableVar' relVar' insVar' insQVar' recordType' = do- let tableVar = varName tableVar'- tableDs <- simpleValD tableVar [t| Table $recordType' |]- [| derivedTable |]- let relVar = varName relVar'- relDs <- simpleValD relVar [t| Relation () $recordType' |]- [| derivedRelation |]- let insVar = varName insVar'- insDs <- simpleValD insVar [t| Insert $recordType' |]- [| derivedInsert id' |]- let insQVar = varName insQVar'- insQDs <- simpleValD insQVar [t| forall p . Relation p $recordType' -> InsertQuery p |]- [| derivedInsertQuery id' |]- return $ concat [tableDs, relDs, insDs, insQDs]---- | 'Table' and 'Relation' templates.-defineTableTypes :: VarName -- ^ Table declaration variable name- -> VarName -- ^ Relation declaration variable name- -> VarName -- ^ Insert statement declaration variable name- -> VarName -- ^ InsertQuery statement declaration variable name- -> TypeQ -- ^ Record type- -> String -- ^ Table name in SQL ex. FOO_SCHEMA.table0- -> [String] -- ^ Column names- -> Q [Dec] -- ^ Table and Relation declaration-defineTableTypes tableVar' relVar' insVar' insQVar' recordType' table columns = do- iDs <- defineTableDerivableInstance recordType' table columns- dDs <- defineTableDerivations tableVar' relVar' insVar' insQVar' recordType'- return $ iDs ++ dDs--tableSQL :: Bool -> SchemaNameMode -> IdentifierQuotation -> String -> String -> String-tableSQL normalize snm iq schema table = case snm of- SchemaQualified -> (qt normalizeS) ++ '.' : (qt normalizeT)- SchemaNotQualified -> (qt normalizeT)- where- normalizeS- | normalize = map toUpper schema- | otherwise = schema- normalizeT- | normalize = map toLower table- | otherwise = table- qt = quote iq--quote :: IdentifierQuotation -> String -> String-quote NoQuotation s = s-quote (Quotation q) s = q : (escape s) ++ q : []- where escape = (>>= (\c -> if c == q then [q, q] else [c]))--derivationVarNameDefault :: String -> VarName-derivationVarNameDefault = (`varNameWithPrefix` "derivationFrom")---- | Make 'TableDerivation' variable expression template from table name using default naming rule.-derivationExpDefault :: String -- ^ Table name string- -> ExpQ -- ^ Result var Exp-derivationExpDefault = toVarExp . derivationVarNameDefault--tableVarNameDefault :: String -> VarName-tableVarNameDefault = (`varNameWithPrefix` "tableOf")---- | Make 'Table' variable expression template from table name using default naming rule.-tableVarExpDefault :: String -- ^ Table name string- -> ExpQ -- ^ Result var Exp-tableVarExpDefault = toVarExp . tableVarNameDefault---- | Make 'Relation' variable expression template from table name using specified naming rule.-relationVarExp :: Config -- ^ Configuration which has naming rules of templates- -> String -- ^ Schema name string- -> String -- ^ Table name string- -> ExpQ -- ^ Result var Exp-relationVarExp config scm = toVarExp . relationVarName (nameConfig config) scm---- | Make template for record 'ProductConstructor' instance using specified naming rule.-defineProductConstructorInstanceWithConfig :: Config -> String -> String -> [TypeQ] -> Q [Dec]-defineProductConstructorInstanceWithConfig config schema table colTypes = do- let tp = recordTemplate (recordConfig $ nameConfig config) schema table- uncurry defineProductConstructorInstance tp colTypes---- | Make templates about table and column metadatas using specified naming rule.-defineTableTypesWithConfig :: Config -- ^ Configuration to generate query with- -> String -- ^ Schema name- -> String -- ^ Table name- -> [((String, TypeQ), Maybe TypeQ)] -- ^ Column names and types and constraint type- -> Q [Dec] -- ^ Result declarations-defineTableTypesWithConfig config schema table columns = do- let nmconfig = nameConfig config- recConfig = recordConfig nmconfig- tableDs <- defineTableTypes- (tableVarNameDefault table)- (relationVarName nmconfig schema table)- (table `varNameWithPrefix` "insert")- (table `varNameWithPrefix` "insertQuery")- (fst $ recordTemplate recConfig schema table)- (tableSQL (normalizedTableName config) (schemaNameMode config) (identifierQuotation config) schema table)- (map ((quote (identifierQuotation config)) . fst . fst) columns)- colsDs <- defineColumnsDefault (recordTypeName recConfig schema table) columns- return $ tableDs ++ colsDs---- | Make templates about table, column and haskell record using specified naming rule.-defineTableTypesAndRecord :: Config -- ^ Configuration to generate query with- -> String -- ^ Schema name- -> String -- ^ Table name- -> [(String, TypeQ)] -- ^ Column names and types- -> [Name] -- ^ Record derivings- -> Q [Dec] -- ^ Result declarations-defineTableTypesAndRecord config schema table columns derives = do- let recConfig = recordConfig $ nameConfig config- recD <- defineRecordTypeWithConfig recConfig schema table columns derives- rconD <- defineProductConstructorInstanceWithConfig config schema table [t | (_, t) <- columns]- ctD <- [d| instance ShowConstantTermsSQL $(fst $ recordTemplate recConfig schema table) |]- tableDs <- defineTableTypesWithConfig config schema table [(c, Nothing) | c <- columns ]- return $ recD ++ rconD ++ ctD ++ tableDs---- | Template of derived primary 'Query'.-definePrimaryQuery :: VarName -- ^ Variable name of result declaration- -> TypeQ -- ^ Parameter type of 'Query'- -> TypeQ -- ^ Record type of 'Query'- -> ExpQ -- ^ 'Relation' expression- -> Q [Dec] -- ^ Result 'Query' declaration-definePrimaryQuery toDef' paramType recType relE = do- let toDef = varName toDef'- simpleValD toDef- [t| Query $paramType $recType |]- [| relationalQuery (primary $relE) |]---- | Template of derived primary 'Update'.-definePrimaryUpdate :: VarName -- ^ Variable name of result declaration- -> TypeQ -- ^ Parameter type of 'Update'- -> TypeQ -- ^ Record type of 'Update'- -> ExpQ -- ^ 'Table' expression- -> Q [Dec] -- ^ Result 'Update' declaration-definePrimaryUpdate toDef' paramType recType tableE = do- let toDef = varName toDef'- simpleValD toDef- [t| KeyUpdate $paramType $recType |]- [| primaryUpdate $tableE |]----- | SQL templates derived from primary key.-defineSqlsWithPrimaryKey :: VarName -- ^ Variable name of select query definition from primary key- -> VarName -- ^ Variable name of update statement definition from primary key- -> TypeQ -- ^ Primary key type- -> TypeQ -- ^ Record type- -> ExpQ -- ^ Relation expression- -> ExpQ -- ^ Table expression- -> Q [Dec] -- ^ Result declarations-defineSqlsWithPrimaryKey sel upd paramType recType relE tableE = do- selD <- definePrimaryQuery sel paramType recType relE- updD <- definePrimaryUpdate upd paramType recType tableE- return $ selD ++ updD---- | SQL templates derived from primary key using default naming rule.-defineSqlsWithPrimaryKeyDefault :: String -- ^ Table name of Database- -> TypeQ -- ^ Primary key type- -> TypeQ -- ^ Record type- -> ExpQ -- ^ Relation expression- -> ExpQ -- ^ Table expression- -> Q [Dec] -- ^ Result declarations-defineSqlsWithPrimaryKeyDefault table =- defineSqlsWithPrimaryKey sel upd- where- sel = table `varNameWithPrefix` "select"- upd = table `varNameWithPrefix` "update"---- | All templates about primary key.-defineWithPrimaryKey :: Config- -> String -- ^ Schema name- -> String -- ^ Table name string- -> TypeQ -- ^ Type of primary key- -> [Int] -- ^ Indexes specifies primary key- -> Q [Dec] -- ^ Result declarations-defineWithPrimaryKey config schema table keyType ixs = do- instD <- defineHasPrimaryKeyInstanceWithConfig config schema table keyType ixs- let recType = fst $ recordTemplate (recordConfig $ nameConfig config) schema table- tableE = tableVarExpDefault table- relE = relationVarExp config schema table- sqlsD <- defineSqlsWithPrimaryKeyDefault table keyType recType relE tableE- return $ instD ++ sqlsD---- | All templates about not-null key.-defineWithNotNullKeyWithConfig :: Config -> String -> String -> Int -> Q [Dec]-defineWithNotNullKeyWithConfig = defineHasNotNullKeyInstanceWithConfig---- | Generate all templtes about table using specified naming rule.-defineTable :: Config -- ^ Configuration to generate query with- -> String -- ^ Schema name string of Database- -> String -- ^ Table name string of Database- -> [(String, TypeQ)] -- ^ Column names and types- -> [Name] -- ^ derivings for Record type- -> [Int] -- ^ Primary key index- -> Maybe Int -- ^ Not null key index- -> Q [Dec] -- ^ Result declarations-defineTable config schema table columns derives primaryIxs mayNotNullIdx = do- tblD <- defineTableTypesAndRecord config schema table columns derives- let pairT x y = appT (appT (tupleT 2) x) y- keyType = foldl1' pairT . map (snd . (columns !!)) $ primaryIxs- primD <- case primaryIxs of- [] -> return []- ixs -> defineWithPrimaryKey config schema table keyType ixs- nnD <- maybeD (\i -> defineWithNotNullKeyWithConfig config schema table i) mayNotNullIdx- return $ tblD ++ primD ++ nnD----- | Unsafely inlining SQL string 'Query' in compile type.-unsafeInlineQuery :: TypeQ -- ^ Query parameter type- -> TypeQ -- ^ Query result type- -> String -- ^ SQL string query to inline- -> VarName -- ^ Variable name for inlined query- -> Q [Dec] -- ^ Result declarations-unsafeInlineQuery p r sql qVar' =- simpleValD (varName qVar')- [t| Query $p $r |]- [| unsafeTypedQuery $(stringE sql) |]---- | Extract param type and result type from defined Relation-reifyRelation :: Name -- ^ Variable name which has Relation type- -> Q (Type, Type) -- ^ Extracted param type and result type from Relation type-reifyRelation relVar = do- relInfo <- reify relVar- case unVarI relInfo of- Just (_, (AppT (AppT (ConT prn) p) r), _)- | prn == ''Relation -> return (p, r)- _ ->- fail $ "expandRelation: Variable must have Relation type: " ++ show relVar---- | Inlining composed 'Query' in compile type.-inlineQuery :: Name -- ^ Top-level variable name which has 'Relation' type- -> Relation p r -- ^ Object which has 'Relation' type- -> Config -- ^ Configuration to generate SQL- -> QuerySuffix -- ^ suffix SQL words- -> String -- ^ Variable name to define as inlined query- -> Q [Dec] -- ^ Result declarations-inlineQuery relVar rel config sufs qns = do- (p, r) <- reifyRelation relVar- unsafeInlineQuery (return p) (return r)- (relationalQuerySQL config rel sufs)- (varCamelcaseName qns)---- | Generate all templates against defined record like type constructor--- other than depending on sql-value type.-makeRelationalRecordDefault :: Name -- ^ Type constructor name- -> Q [Dec] -- ^ Result declaration-makeRelationalRecordDefault recTypeName = do- let recTypeConName = ConName recTypeName- ((tyCon, dataCon), (mayNs, cts)) <- Record.reifyRecordType recTypeName- pw <- Record.defineColumnOffsets recTypeConName cts- cs <- maybe- (return [])- (\ns -> defineColumnsDefault recTypeConName- [ ((nameBase n, ct), Nothing) | n <- ns | ct <- cts ])- mayNs- pc <- defineProductConstructorInstance tyCon dataCon cts- ct <- [d| instance ShowConstantTermsSQL $tyCon |]- return $ concat [pw, cs, pc, ct]
− src/Database/Relational/Query/Table.hs
@@ -1,72 +0,0 @@--- |--- Module : Database.Relational.Query.Table--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines table type which has table metadatas.-module Database.Relational.Query.Table (- -- * Phantom typed table type- Table, unType, name, shortName, width, columns, index, table, toMaybe, recordWidth,-- -- * Table existence inference- TableDerivable (..)- ) where--import Data.Array (listArray)--import Database.Record.Persistable (PersistableWidth, PersistableRecordWidth, unsafePersistableRecordWidth)--import Database.Relational.Query.Internal.UntypedTable (Untyped (Untyped), name', width', columns', (!))-import Database.Relational.Query.Internal.SQL (StringSQL, stringSQL, )----- | Phantom typed table type-newtype Table r = Table Untyped---- | Untype table.-unType :: Table t -> Untyped-unType (Table u) = u---- | Name string of table in SQL-name :: Table r -> String-name = name' . unType---- | Not qualified name string of table in SQL-shortName :: Table r -> String-shortName = tail . dropWhile (/= '.') . name---- | Width of table-width :: Table r -> Int-width = width' . unType---- | Column name strings in SQL-columns :: Table r -> [StringSQL]-columns = columns' . unType---- | Column name string in SQL specified by index-index :: Table r- -> Int -- ^ Column index- -> StringSQL -- ^ Column name String in SQL-index = (!) . unType---- | Cast phantom type into 'Maybe' type.-toMaybe :: Table r -> Table (Maybe r)-toMaybe (Table t) = Table t---- | Unsafely generate phantom typed table type.-table :: String -> [String] -> Table r-table n f = Table $ Untyped n w fa where- w = length f- fa = listArray (0, w - 1) $ map stringSQL f---- | Inference rule of 'Table' existence.-class PersistableWidth r => TableDerivable r where- derivedTable :: Table r---- | PersistableRecordWidth of table-recordWidth :: Table r -> PersistableRecordWidth r-recordWidth = unsafePersistableRecordWidth . width
− src/Database/Relational/Query/TupleInstances.hs
@@ -1,28 +0,0 @@-{-# OPTIONS_GHC -fno-warn-orphans #-}--{-# LANGUAGE TemplateHaskell #-}-{-# LANGUAGE FlexibleInstances #-}-{-# LANGUAGE ScopedTypeVariables #-}---- |--- Module : Database.Relational.Query.TupleInstances--- Copyright : 2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines ProductConstructor instances and projection path objects of tuple types.-module Database.Relational.Query.TupleInstances where--import Control.Applicative ((<$>))--import Database.Relational.Query.BaseTH- (defineTuplePi, defineTupleProductConstructor, defineTupleShowConstantInstance,)---$(concat <$> mapM defineTupleProductConstructor [2..7])-$(concat <$> mapM defineTuplePi [2..7])-$(concat <$> mapM defineTupleShowConstantInstance [2..7])--- Generic instances of tuple types are generated from 2 to 7 in GHC.Generics.
− src/Database/Relational/Query/Type.hs
@@ -1,353 +0,0 @@--- |--- Module : Database.Relational.Query.Type--- Copyright : 2013-2017 Kei Hibino--- License : BSD3------ Maintainer : ex8k.hibino@gmail.com--- Stability : experimental--- Portability : unknown------ This module defines typed SQL.-module Database.Relational.Query.Type (- -- * Typed query statement- Query (..), unsafeTypedQuery,-- relationalQuery', relationalQuery,-- relationalQuerySQL,-- -- * Typed update statement- KeyUpdate (..), unsafeTypedKeyUpdate, typedKeyUpdate, typedKeyUpdateTable, derivedKeyUpdate,- Update (..), unsafeTypedUpdate, typedUpdate', typedUpdate, derivedUpdate', derivedUpdate,- typedUpdateAllColumn, derivedUpdateAllColumn', derivedUpdateAllColumn,- restrictedUpdateAllColumn, restrictedUpdateTableAllColumn,-- updateSQL,-- -- * Typed insert statement- Insert (..), untypeChunkInsert, chunkSizeOfInsert,- unsafeTypedInsert', unsafeTypedInsert, typedInsert', typedInsert, derivedInsert,- typedInsertValue', typedInsertValue, derivedInsertValue', derivedInsertValue,- InsertQuery (..), unsafeTypedInsertQuery, typedInsertQuery', typedInsertQuery, derivedInsertQuery,-- insertQuerySQL,-- -- * Typed delete statement- Delete (..), unsafeTypedDelete, typedDelete', typedDelete, derivedDelete', derivedDelete,-- deleteSQL,-- -- * Generalized interfaces- UntypeableNoFetch (..)- ) where--import Data.Monoid ((<>))--import Database.Record (PersistableWidth)--import Database.Relational.Query.Internal.Config (Config, defaultConfig)-import Database.Relational.Query.Internal.SQL (showStringSQL)--import Database.Relational.Query.Monad.BaseType (Relation, sqlFromRelationWith)-import Database.Relational.Query.Monad.Restrict (RestrictedStatement)-import Database.Relational.Query.Monad.Assign (AssignStatement)-import Database.Relational.Query.Monad.Register (Register)-import Database.Relational.Query.Relation (tableOf)-import Database.Relational.Query.Effect- (Restriction, restriction', UpdateTarget, updateTarget', liftTargetAllColumn', InsertTarget, insertTarget',- sqlWhereFromRestriction, sqlFromUpdateTarget, piRegister, sqlChunkFromInsertTarget, sqlFromInsertTarget)-import Database.Relational.Query.Pi (Pi)-import Database.Relational.Query.Table (Table, TableDerivable, derivedTable)-import Database.Relational.Query.Projectable (PlaceHolders)-import Database.Relational.Query.SQL- (QuerySuffix, showsQuerySuffix, insertPrefixSQL,- updateOtherThanKeySQL, updatePrefixSQL, deletePrefixSQL)----- | Query type with place-holder parameter 'p' and query result type 'a'.-newtype Query p a = Query { untypeQuery :: String }---- | Unsafely make typed 'Query' from SQL string.-unsafeTypedQuery :: String -- ^ Query SQL to type- -> Query p a -- ^ Typed result-unsafeTypedQuery = Query---- | Show query SQL string-instance Show (Query p a) where- show = untypeQuery---- | From 'Relation' into untyped SQL query string.-relationalQuerySQL :: Config -> Relation p r -> QuerySuffix -> String-relationalQuerySQL config rel qsuf = showStringSQL $ sqlFromRelationWith rel config <> showsQuerySuffix qsuf---- | From 'Relation' into typed 'Query' with suffix SQL words.-relationalQuery' :: Relation p r -> QuerySuffix -> Query p r-relationalQuery' rel qsuf = unsafeTypedQuery $ relationalQuerySQL defaultConfig rel qsuf---- | From 'Relation' into typed 'Query'.-relationalQuery :: Relation p r -> Query p r-relationalQuery = (`relationalQuery'` [])----- | Update type with key type 'p' and update record type 'a'.--- Columns to update are record columns other than key columns,--- So place-holder parameter type is the same as record type 'a'.-data KeyUpdate p a = KeyUpdate { updateKey :: Pi a p- , untypeKeyUpdate :: String- }---- | Unsafely make typed 'KeyUpdate' from SQL string.-unsafeTypedKeyUpdate :: Pi a p -> String -> KeyUpdate p a-unsafeTypedKeyUpdate = KeyUpdate---- | Make typed 'KeyUpdate' from 'Table' and key columns selector 'Pi'.-typedKeyUpdate :: Table a -> Pi a p -> KeyUpdate p a-typedKeyUpdate tbl key = unsafeTypedKeyUpdate key $ updateOtherThanKeySQL tbl key---- | Make typed 'KeyUpdate' object using derived info specified by 'Relation' type.-typedKeyUpdateTable :: TableDerivable r => Relation () r -> Pi r p -> KeyUpdate p r-typedKeyUpdateTable = typedKeyUpdate . tableOf---- derivedKeyUpdate'--- Config parameter is not yet required for KeyUpdate.---- | Make typed 'KeyUpdate' from derived table and key columns selector 'Pi'.-derivedKeyUpdate :: TableDerivable r => Pi r p -> KeyUpdate p r-derivedKeyUpdate = typedKeyUpdate derivedTable---- | Show update SQL string-instance Show (KeyUpdate p a) where- show = untypeKeyUpdate----- | Update type with place-holder parameter 'p'.-newtype Update p = Update { untypeUpdate :: String }---- | Unsafely make typed 'Update' from SQL string.-unsafeTypedUpdate :: String -> Update p-unsafeTypedUpdate = Update---- | Make untyped update SQL string from 'Table' and 'UpdateTarget'.-updateSQL :: Config -> Table r -> UpdateTarget p r -> String-updateSQL config tbl ut = showStringSQL $ updatePrefixSQL tbl <> sqlFromUpdateTarget config tbl ut---- | Make typed 'Update' from 'Config', 'Table' and 'UpdateTarget'.-typedUpdate' :: Config -> Table r -> UpdateTarget p r -> Update p-typedUpdate' config tbl ut = unsafeTypedUpdate $ updateSQL config tbl ut---- | Make typed 'Update' using 'defaultConfig', 'Table' and 'UpdateTarget'.-typedUpdate :: Table r -> UpdateTarget p r -> Update p-typedUpdate = typedUpdate' defaultConfig--targetTable :: TableDerivable r => UpdateTarget p r -> Table r-targetTable = const derivedTable---- | Make typed 'Update' from 'Config', derived table and 'AssignStatement'-derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p-derivedUpdate' config utc = typedUpdate' config (targetTable ut) ut where- ut = updateTarget' utc---- | Make typed 'Update' from 'defaultConfig', derived table and 'AssignStatement'-derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p-derivedUpdate = derivedUpdate' defaultConfig----- | Make typed 'Update' from 'Config', 'Table' and 'Restriction'.--- Update target is all column.-typedUpdateAllColumn' :: PersistableWidth r- => Config- -> Table r- -> Restriction p r- -> Update (r, p)-typedUpdateAllColumn' config tbl r = typedUpdate' config tbl $ liftTargetAllColumn' r---- | Make typed 'Update' from 'Table' and 'Restriction'.--- Update target is all column.-typedUpdateAllColumn :: PersistableWidth r- => Table r- -> Restriction p r- -> Update (r, p)-typedUpdateAllColumn tbl r = typedUpdate tbl $ liftTargetAllColumn' r---- | Make typed 'Update' from 'Config', derived table and 'AssignStatement'.--- Update target is all column.-derivedUpdateAllColumn' :: (PersistableWidth r, TableDerivable r)- => Config- -> RestrictedStatement r (PlaceHolders p)- -> Update (r, p)-derivedUpdateAllColumn' config = typedUpdateAllColumn' config derivedTable .restriction'---- | Make typed 'Update' from 'defaultConfig', derived table and 'AssignStatement'.--- Update target is all column.-derivedUpdateAllColumn :: (PersistableWidth r, TableDerivable r)- => RestrictedStatement r (PlaceHolders p)- -> Update (r, p)-derivedUpdateAllColumn = derivedUpdateAllColumn' defaultConfig--{-# DEPRECATED restrictedUpdateAllColumn "Use derivedUpdateAllColumn or typedUpdateAllColumn instead of this." #-}--- | Directly make typed 'Update' from 'Table' and 'Restrict' monad context.--- Update target is all column.-restrictedUpdateAllColumn :: PersistableWidth r- => Table r- -> RestrictedStatement r (PlaceHolders p) -- ^ 'Restrict' monad context- -> Update (r, p)-restrictedUpdateAllColumn tbl = typedUpdateAllColumn tbl . restriction'--{-# DEPRECATED restrictedUpdateTableAllColumn "Use derivedUpdateAllColumn or typedUpdateAllColumn instead of this." #-}--- | Directly make typed 'Update' from 'Table' and 'Restrict' monad context.--- Update target is all column.-restrictedUpdateTableAllColumn :: (PersistableWidth r, TableDerivable r)- => Relation () r- -> RestrictedStatement r (PlaceHolders p)- -> Update (r, p)-restrictedUpdateTableAllColumn = restrictedUpdateAllColumn . tableOf---- | Show update SQL string-instance Show (Update p) where- show = untypeUpdate----- | Insert type to insert record type 'a'.-data Insert a =- Insert- { untypeInsert :: String- , chunkedInsert :: Maybe (String, Int)- }---- | Statement to use chunked insert-untypeChunkInsert :: Insert a -> String-untypeChunkInsert ins = maybe (untypeInsert ins) fst $ chunkedInsert ins---- | Size to use chunked insert-chunkSizeOfInsert :: Insert a -> Int-chunkSizeOfInsert = maybe 1 snd . chunkedInsert---- | Unsafely make typed 'Insert' from single insert and chunked insert SQL.-unsafeTypedInsert' :: String -> String -> Int -> Insert a-unsafeTypedInsert' s = curry (Insert s . Just)---- | Unsafely make typed 'Insert' from single insert SQL.-unsafeTypedInsert :: String -> Insert a-unsafeTypedInsert s = Insert s Nothing---- | Make typed 'Insert' from 'Table' and columns selector 'Pi' with configuration parameter.-typedInsert' :: PersistableWidth r => Config -> Table r -> Pi r r' -> Insert r'-typedInsert' config tbl =- typedInsertValue' config tbl . insertTarget' . piRegister---- | Make typed 'Insert' from 'Table' and columns selector 'Pi'.-typedInsert :: PersistableWidth r => Table r -> Pi r r' -> Insert r'-typedInsert = typedInsert' defaultConfig---- | Table type inferred 'Insert'.-derivedInsert :: (PersistableWidth r, TableDerivable r) => Pi r r' -> Insert r'-derivedInsert = typedInsert derivedTable---- | Make typed 'Insert' from 'Config', 'Table' and monadic builded 'InsertTarget' object.-typedInsertValue' :: Config -> Table r -> InsertTarget p r -> Insert p-typedInsertValue' config tbl it =- unsafeTypedInsert'- (showStringSQL $ sqlFromInsertTarget config tbl it)- (showStringSQL ci) n- where- (ci, n) = sqlChunkFromInsertTarget config tbl it---- | Make typed 'Insert' from 'Table' and monadic builded 'InsertTarget' object.-typedInsertValue :: Table r -> InsertTarget p r -> Insert p-typedInsertValue = typedInsertValue' defaultConfig---- | Make typed 'Insert' from 'Config', derived table and monadic builded 'Register' object.-derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p-derivedInsertValue' config rs = typedInsertValue' config (rt rs) $ insertTarget' rs- where- rt :: TableDerivable r => Register r (PlaceHolders p) -> Table r- rt = const derivedTable---- | Make typed 'Insert' from 'defaultConfig', derived table and monadic builded 'Register' object.-derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p-derivedInsertValue = derivedInsertValue' defaultConfig---- | Show insert SQL string.-instance Show (Insert a) where- show = untypeInsert---- | InsertQuery type.-newtype InsertQuery p = InsertQuery { untypeInsertQuery :: String }---- | Unsafely make typed 'InsertQuery' from SQL string.-unsafeTypedInsertQuery :: String -> InsertQuery p-unsafeTypedInsertQuery = InsertQuery---- | Make untyped insert select SQL string from 'Table', 'Pi' and 'Relation'.-insertQuerySQL :: Config -> Table r -> Pi r r' -> Relation p r' -> String-insertQuerySQL config tbl pi' rel = showStringSQL $ insertPrefixSQL pi' tbl <> sqlFromRelationWith rel config---- | Make typed 'InsertQuery' from columns selector 'Table', 'Pi' and 'Relation' with configuration parameter.-typedInsertQuery' :: Config -> Table r -> Pi r r' -> Relation p r' -> InsertQuery p-typedInsertQuery' config tbl pi' rel = unsafeTypedInsertQuery $ insertQuerySQL config tbl pi' rel---- | Make typed 'InsertQuery' from columns selector 'Table', 'Pi' and 'Relation'.-typedInsertQuery :: Table r -> Pi r r' -> Relation p r' -> InsertQuery p-typedInsertQuery = typedInsertQuery' defaultConfig---- | Table type inferred 'InsertQuery'.-derivedInsertQuery :: TableDerivable r => Pi r r' -> Relation p r' -> InsertQuery p-derivedInsertQuery = typedInsertQuery derivedTable---- | Show insert SQL string.-instance Show (InsertQuery p) where- show = untypeInsertQuery----- | Delete type with place-holder parameter 'p'.-newtype Delete p = Delete { untypeDelete :: String }---- | Unsafely make typed 'Delete' from SQL string.-unsafeTypedDelete :: String -> Delete p-unsafeTypedDelete = Delete---- | Make untyped delete SQL string from 'Table' and 'Restriction'.-deleteSQL :: Config -> Table r -> Restriction p r -> String-deleteSQL config tbl r = showStringSQL $ deletePrefixSQL tbl <> sqlWhereFromRestriction config tbl r---- | Make typed 'Delete' from 'Config', 'Table' and 'Restriction'.-typedDelete' :: Config -> Table r -> Restriction p r -> Delete p-typedDelete' config tbl r = unsafeTypedDelete $ deleteSQL config tbl r---- | Make typed 'Delete' from 'Table' and 'Restriction'.-typedDelete :: Table r -> Restriction p r -> Delete p-typedDelete = typedDelete' defaultConfig--restrictedTable :: TableDerivable r => Restriction p r -> Table r-restrictedTable = const derivedTable---- | Make typed 'Delete' from 'Config', derived table and 'RestrictContext'-derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p-derivedDelete' config rc = typedDelete' config (restrictedTable rs) rs where- rs = restriction' rc---- | Make typed 'Delete' from 'defaultConfig', derived table and 'RestrictContext'-derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p-derivedDelete = derivedDelete' defaultConfig---- | Show delete SQL string-instance Show (Delete p) where- show = untypeDelete----- | Untype interface for typed no-result type statments--- with single type parameter which represents place-holder parameter 'p'.-class UntypeableNoFetch s where- untypeNoFetch :: s p -> String--instance UntypeableNoFetch Insert where- untypeNoFetch = untypeInsert--instance UntypeableNoFetch InsertQuery where- untypeNoFetch = untypeInsertQuery--instance UntypeableNoFetch Update where- untypeNoFetch = untypeUpdate--instance UntypeableNoFetch Delete where- untypeNoFetch = untypeDelete
+ src/Database/Relational/Record.hs view
@@ -0,0 +1,203 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}+{-# LANGUAGE FlexibleContexts #-}+{-# LANGUAGE MultiParamTypeClasses #-}++-- |+-- Module : Database.Relational.Record+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines interfaces of projected record type.+module Database.Relational.Record (+ -- * Record data structure and interface+ Record,++ width,+ columns,+ untype,++ unsafeFromSqlTerms,+ unsafeFromQualifiedSubQuery,+ unsafeFromScalarSubQuery,+ unsafeFromTable,++ unsafeStringSql,++ -- * Projections+ pi, piMaybe, piMaybe',+ wpi,++ flattenMaybe, just,++ unsafeToAggregated, unsafeToFlat, unsafeChangeContext,+ unsafeStringSqlNotNullMaybe,++ -- * List of Record+ RecordList, list, unsafeListFromSubQuery,+ unsafeStringSqlList+ ) where++import Prelude hiding (pi)+import Data.Functor.ProductIsomorphic+ (ProductIsoFunctor, (|$|), ProductIsoApplicative, pureP, (|*|),+ ProductIsoEmpty, pureE, peRight, peLeft, )++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.Internal.ContextType (Aggregated, Flat)+import Database.Relational.Internal.String (StringSQL, listStringSQL, rowStringSQL)+import Database.Relational.SqlSyntax+ (SubQuery, Qualified, Tuple, Record,+ recordRawColumns, tupleFromJoinedSubQuery,)+import qualified Database.Relational.SqlSyntax as Syntax++import Database.Relational.Table (Table)+import qualified Database.Relational.Table as Table+import Database.Relational.Pi (Pi)+import qualified Database.Relational.Pi.Unsafe as UnsafePi+++-- | Unsafely get SQL term from 'Record'.+unsafeStringSql :: Record c r -> StringSQL+unsafeStringSql = rowStringSQL . recordRawColumns++-- | Get column SQL string list of record.+columns :: Record c r -- ^ Source 'Record'+ -> [StringSQL] -- ^ Result SQL string list+columns = recordRawColumns++-- | Width of 'Record'.+width :: Record c r -> Int+width = Syntax.recordWidth++-- | Get untyped tuple.+untype :: Record c r -> Tuple+untype = Syntax.untypeRecord+++-- | Unsafely generate 'Record' from qualified (joined) sub-query.+unsafeFromQualifiedSubQuery :: Qualified SubQuery -> Record c t+unsafeFromQualifiedSubQuery = Syntax.record . tupleFromJoinedSubQuery++-- | Unsafely generate 'Record' from scalar sub-query.+unsafeFromScalarSubQuery :: SubQuery -> Record c t+unsafeFromScalarSubQuery = Syntax.typeFromScalarSubQuery++-- | Unsafely generate unqualified 'Record' from 'Table'.+unsafeFromTable :: Table r+ -> Record c r+unsafeFromTable = Syntax.typeFromRawColumns . Table.columns++-- | Unsafely generate 'Record' from SQL expression strings.+unsafeFromSqlTerms :: [StringSQL] -> Record c t+unsafeFromSqlTerms = Syntax.typeFromRawColumns+++-- | Unsafely trace projection path.+unsafeProject :: PersistableRecordWidth a -> Record c a' -> Pi a b -> Record c b'+unsafeProject w p pi' =+ Syntax.typeFromRawColumns+ . (UnsafePi.pi w pi')+ . columns $ p++-- | Trace projection path to get narrower 'Record'.+wpi :: PersistableRecordWidth a+ -> Record c a -- ^ Source 'Record'+ -> Pi a b -- ^ Projection path+ -> Record c b -- ^ Narrower 'Record'+wpi = unsafeProject++-- | Trace projection path to get narrower 'Record'.+pi :: PersistableWidth a+ => Record c a -- ^ Source 'Record'+ -> Pi a b -- ^ Record path+ -> Record c b -- ^ Narrower 'Record'+pi = unsafeProject persistableWidth++-- | Trace projection path to get narrower 'Record'. From 'Maybe' type to 'Maybe' type.+piMaybe :: PersistableWidth a+ => Record c (Maybe a) -- ^ Source 'Record'. 'Maybe' type+ -> Pi a b -- ^ Projection path+ -> Record c (Maybe b) -- ^ Narrower 'Record'. 'Maybe' type result+piMaybe = unsafeProject persistableWidth++-- | Trace projection path to get narrower 'Record'. From 'Maybe' type to 'Maybe' type.+-- Leaf type of projection path is 'Maybe'.+piMaybe' :: PersistableWidth a+ => Record c (Maybe a) -- ^ Source 'Record'. 'Maybe' type+ -> Pi a (Maybe b) -- ^ Projection path. 'Maybe' type leaf+ -> Record c (Maybe b) -- ^ Narrower 'Record'. 'Maybe' type result+piMaybe' = unsafeProject persistableWidth++unsafeCast :: Record c r -> Record c r'+unsafeCast = Syntax.record . Syntax.untypeRecord++-- | Composite nested 'Maybe' on record phantom type.+flattenMaybe :: Record c (Maybe (Maybe a)) -> Record c (Maybe a)+flattenMaybe = unsafeCast++-- | Cast into 'Maybe' on record phantom type.+just :: Record c r -> Record c (Maybe r)+just = unsafeCast++-- | Unsafely cast context type tag.+unsafeChangeContext :: Record c r -> Record c' r+unsafeChangeContext = Syntax.record . Syntax.untypeRecord++-- | Unsafely lift to aggregated context.+unsafeToAggregated :: Record Flat r -> Record Aggregated r+unsafeToAggregated = unsafeChangeContext++-- | Unsafely down to flat context.+unsafeToFlat :: Record Aggregated r -> Record Flat r+unsafeToFlat = unsafeChangeContext++notNullMaybeConstraint :: HasColumnConstraint NotNull r => Record c (Maybe r) -> NotNullColumnConstraint r+notNullMaybeConstraint = const KeyConstraint.columnConstraint++-- | Unsafely get SQL string expression of not null key record.+unsafeStringSqlNotNullMaybe :: HasColumnConstraint NotNull r => Record c (Maybe r) -> StringSQL+unsafeStringSqlNotNullMaybe p = (!! KeyConstraint.index (notNullMaybeConstraint p)) . columns $ p++pempty :: Record c ()+pempty = Syntax.record []++-- | Map 'Record' which result type is record.+instance ProductIsoFunctor (Record c) where+ _ |$| p = unsafeCast p++-- | Compose 'Record' using applicative style.+instance ProductIsoApplicative (Record c) where+ pureP _ = unsafeCast pempty+ pf |*| pa = Syntax.record $ Syntax.untypeRecord pf ++ Syntax.untypeRecord pa++instance ProductIsoEmpty (Record c) () where+ pureE = pureP ()+ peRight = unsafeCast+ peLeft = unsafeCast++-- | Projected record list type for row list.+data RecordList p t = List [p t]+ | Sub SubQuery++-- | Make projected record list from 'Record' list.+list :: [p t] -> RecordList p t+list = List++-- | Make projected record list from 'SubQuery'.+unsafeListFromSubQuery :: SubQuery -> RecordList p t+unsafeListFromSubQuery = Sub++-- | Map record show operatoions and concatinate to single SQL expression.+unsafeStringSqlList :: (p t -> StringSQL) -> RecordList p t -> StringSQL+unsafeStringSqlList sf = d where+ d (List ps) = listStringSQL $ map sf ps+ d (Sub sub) = SQL.paren $ Syntax.showSQL sub
+ src/Database/Relational/Relation.hs view
@@ -0,0 +1,192 @@+{-# LANGUAGE FlexibleContexts #-}++-- |+-- Module : Database.Relational.Relation+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module integrate monadic operations to compose complex queries+-- with re-usable Relation type.+module Database.Relational.Relation (+ -- * Relation type+ table, derivedRelation, tableOf,+ relation, relation',+ aggregateRelation, aggregateRelation',++ UniqueRelation,+ unsafeUnique, unUnique,++ uniqueRelation', aggregatedUnique,++ -- * Query using relation+ query, queryMaybe, queryList, queryList', queryScalar, queryScalar',+ uniqueQuery', uniqueQueryMaybe',+ ) where++import Control.Applicative ((<$>))++import Database.Relational.Internal.ContextType (Flat, Aggregated)+import Database.Relational.SqlSyntax (NodeAttr(Just', Maybe), Record, )++import Database.Relational.Monad.BaseType+ (ConfigureQuery, qualifyQuery,+ Relation, unsafeTypeRelation, untypeRelation, relationWidth)+import Database.Relational.Monad.Class+ (MonadQualify (liftQualify), MonadQuery (query', queryMaybe'), )+import Database.Relational.Monad.Simple (QuerySimple, SimpleQuery)+import qualified Database.Relational.Monad.Simple as Simple+import Database.Relational.Monad.Aggregate (QueryAggregate, AggregatedQuery)+import qualified Database.Relational.Monad.Aggregate as Aggregate+import Database.Relational.Monad.Unique (QueryUnique, unsafeUniqueSubQuery)+import qualified Database.Relational.Monad.Unique as Unique+import Database.Relational.Table (Table, TableDerivable, derivedTable)+import qualified Database.Relational.Table as Table+import Database.Relational.Scalar (ScalarDegree)+import Database.Relational.Pi (Pi)+import Database.Relational.Record (RecordList)+import qualified Database.Relational.Record as Record+import Database.Relational.Projectable+ (PlaceHolders, unitPlaceHolder, unsafeAddPlaceHolders, unsafePlaceHolders, )+++-- | Simple 'Relation' from 'Table'.+table :: Table r -> Relation () r+table = unsafeTypeRelation . return . Table.toSubQuery++-- | Inferred 'Relation'.+derivedRelation :: TableDerivable r => Relation () r+derivedRelation = table derivedTable++-- | Interface to derive 'Table' type object.+tableOf :: TableDerivable r => Relation () r -> Table r+tableOf = const derivedTable++placeHoldersFromRelation :: Relation p r -> PlaceHolders p+placeHoldersFromRelation = const unsafePlaceHolders++-- | Join sub-query. Query result is not 'Maybe'.+query :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation () r+ -> m (Record Flat r)+query = fmap snd . query'++-- | Join sub-query. Query result is 'Maybe'.+-- The combinations of 'query' and 'queryMaybe' express+-- inner joins, left outer joins, right outer joins, and full outer joins.+-- Here is an example of a right outer join:+--+-- @+-- outerJoin = relation $ do+-- e <- queryMaybe employee+-- d <- query department+-- on $ e ?! E.deptId' .=. just (d ! D.deptId')+-- return $ (,) |$| e |*| d+-- @+queryMaybe :: (MonadQualify ConfigureQuery m, MonadQuery m)+ => Relation () r+ -> m (Record Flat (Maybe r))+queryMaybe = fmap snd . queryMaybe'++queryList0 :: MonadQualify ConfigureQuery m => Relation p r -> m (RecordList (Record c) r)+queryList0 = liftQualify+ . fmap Record.unsafeListFromSubQuery+ . untypeRelation++-- | List sub-query, for /IN/ and /EXIST/ with place-holder parameter 'p'.+queryList' :: MonadQualify ConfigureQuery m+ => Relation p r+ -> m (PlaceHolders p, RecordList (Record c) r)+queryList' rel = do+ ql <- queryList0 rel+ return (placeHoldersFromRelation rel, ql)++-- | List sub-query, for /IN/ and /EXIST/.+queryList :: MonadQualify ConfigureQuery m+ => Relation () r+ -> m (RecordList (Record c) r)+queryList = queryList0++addUnitPH :: Functor f => f t -> f (PlaceHolders (), t)+addUnitPH = ((,) unitPlaceHolder <$>)++-- | Finalize 'QuerySimple' monad and generate 'Relation' with place-holder parameter 'p'.+relation' :: SimpleQuery p r -> Relation p r+relation' = unsafeTypeRelation . Simple.toSubQuery++-- | Finalize 'QuerySimple' monad and generate 'Relation'.+relation :: QuerySimple (Record Flat r) -> Relation () r+relation = relation' . addUnitPH++-- | Finalize 'QueryAggregate' monad and geneate 'Relation' with place-holder parameter 'p'.+aggregateRelation' :: AggregatedQuery p r -> Relation p r+aggregateRelation' = unsafeTypeRelation . Aggregate.toSubQuery++-- | Finalize 'QueryAggregate' monad and geneate 'Relation'.+aggregateRelation :: QueryAggregate (Record Aggregated r) -> Relation () r+aggregateRelation = aggregateRelation' . addUnitPH+++-- | Unique relation type to compose scalar queries.+newtype UniqueRelation p c r = Unique (Relation p r)++-- | Unsafely specify unique relation.+unsafeUnique :: Relation p r -> UniqueRelation p c r+unsafeUnique = Unique++-- | Discard unique attribute.+unUnique :: UniqueRelation p c r -> Relation p r+unUnique (Unique r) = r++-- | Basic monadic join operation using 'MonadQuery'.+uniqueQueryWithAttr :: NodeAttr+ -> UniqueRelation p c r+ -> QueryUnique (PlaceHolders p, Record c r)+uniqueQueryWithAttr attr = unsafeAddPlaceHolders . run where+ run rel = do+ q <- liftQualify $ do+ sq <- untypeRelation (unUnique rel)+ qualifyQuery sq+ Record.unsafeChangeContext <$> unsafeUniqueSubQuery attr q++-- | Join unique sub-query with place-holder parameter 'p'.+uniqueQuery' :: UniqueRelation p c r+ -> QueryUnique (PlaceHolders p, Record c r)+uniqueQuery' = uniqueQueryWithAttr Just'++-- | Join unique sub-query with place-holder parameter 'p'. Query result is 'Maybe'.+uniqueQueryMaybe' :: UniqueRelation p c r+ -> QueryUnique (PlaceHolders p, Record c (Maybe r))+uniqueQueryMaybe' pr = do+ (ph, pj) <- uniqueQueryWithAttr Maybe pr+ return (ph, Record.just pj)++-- | Finalize 'QueryUnique' monad and generate 'UniqueRelation'.+uniqueRelation' :: QueryUnique (PlaceHolders p, Record c r) -> UniqueRelation p c r+uniqueRelation' = unsafeUnique . unsafeTypeRelation . Unique.toSubQuery++-- | Aggregated 'UniqueRelation'.+aggregatedUnique :: Relation ph r+ -> Pi r a+ -> (Record Flat a -> Record Aggregated b)+ -> UniqueRelation ph Flat b+aggregatedUnique rel k ag = unsafeUnique . aggregateRelation' $ do+ (ph, a) <- query' rel+ return (ph, ag $ Record.wpi (relationWidth rel) a k)++-- | Scalar sub-query with place-holder parameter 'p'.+queryScalar' :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => UniqueRelation p c r+ -> m (PlaceHolders p, Record c (Maybe r))+queryScalar' ur =+ unsafeAddPlaceHolders . liftQualify $+ Record.unsafeFromScalarSubQuery <$> untypeRelation (unUnique ur)++-- | Scalar sub-query.+queryScalar :: (MonadQualify ConfigureQuery m, ScalarDegree r)+ => UniqueRelation () c r+ -> m (Record c (Maybe r))+queryScalar = fmap snd . queryScalar'
+ src/Database/Relational/Scalar.hs view
@@ -0,0 +1,32 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}++-- |+-- Module : Database.Relational.Scalar+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines type classes and templates for scalar queries.+module Database.Relational.Scalar (+ -- * Single degree constraint+ ScalarDegree, defineScalarDegree+ ) where++import Language.Haskell.TH (Q, TypeQ, Dec)++import Database.Record (PersistableWidth)+++-- | Constraint which represents scalar degree.+class PersistableWidth ct => ScalarDegree ct++instance ScalarDegree ct => ScalarDegree (Maybe ct)++-- | 'ScalarDegree' instance templates.+defineScalarDegree :: TypeQ -> Q [Dec]+defineScalarDegree typeCon = do+ [d| instance ScalarDegree $(typeCon) |]
+ src/Database/Relational/Set.hs view
@@ -0,0 +1,213 @@+-- |+-- Module : Database.Relational.Set+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines set operations on monadic Relation operations.+module Database.Relational.Set (+ -- * Direct style join+ JoinRestriction,+ inner', left', right', full',+ inner, left, right, full,+ on',++ -- * Relation append+ union, except, intersect,+ unionAll, exceptAll, intersectAll,++ union', except', intersect',+ unionAll', exceptAll', intersectAll',+ ) where++import Data.Functor.ProductIsomorphic ((|$|), (|*|))++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax+ (Duplication (Distinct, All), SubQuery, Predicate, Record, )+import qualified Database.Relational.SqlSyntax as Syntax++import Database.Relational.Monad.BaseType+ (Relation, unsafeTypeRelation, untypeRelation, )+import Database.Relational.Monad.Class (MonadQuery (query', queryMaybe'), on)+import Database.Relational.Monad.Simple (QuerySimple)+import Database.Relational.Projectable (PlaceHolders)+import Database.Relational.Relation (relation', relation, query, queryMaybe, )+++-- | Restriction predicate function type for direct style join operator,+-- used on predicates of direct join style as follows.+--+-- @+-- do xy <- query $+-- relX `inner` relY `on'` [ \x y -> ... ] -- this lambda form has JoinRestriction type+-- ...+-- @+type JoinRestriction a b = Record Flat a -> Record Flat b -> Predicate Flat++-- | Basic direct join operation with place-holder parameters.+join' :: (qa -> QuerySimple (PlaceHolders pa, Record Flat a))+ -> (qb -> QuerySimple (PlaceHolders pb, Record Flat b))+ -> qa+ -> qb+ -> [JoinRestriction a b]+ -> Relation (pa, pb) (a, b)+join' qL qR r0 r1 rs = relation' $ do+ (ph0, pj0) <- qL r0+ (ph1, pj1) <- qR r1+ sequence_ [ on $ f pj0 pj1 | f <- rs ]+ return ((,) |$| ph0 |*| ph1, (,) |$| pj0 |*| pj1)++-- | Direct inner join with place-holder parameters.+inner' :: Relation pa a -- ^ Left query to join+ -> Relation pb b -- ^ Right query to join+ -> [JoinRestriction a b] -- ^ Join restrictions+ -> Relation (pa, pb) (a, b) -- ^ Result joined relation+inner' = join' query' query'++-- | Direct left outer join with place-holder parameters.+left' :: Relation pa a -- ^ Left query to join+ -> Relation pb b -- ^ Right query to join+ -> [JoinRestriction a (Maybe b)] -- ^ Join restrictions+ -> Relation (pa, pb) (a, Maybe b) -- ^ Result joined relation+left' = join' query' queryMaybe'++-- | Direct right outer join with place-holder parameters.+right' :: Relation pa a -- ^ Left query to join+ -> Relation pb b -- ^ Right query to join+ -> [JoinRestriction (Maybe a) b] -- ^ Join restrictions+ -> Relation (pa, pb)(Maybe a, b) -- ^ Result joined relation+right' = join' queryMaybe' query'++-- | Direct full outer join with place-holder parameters.+full' :: Relation pa a -- ^ Left query to join+ -> Relation pb b -- ^ Right query to join+ -> [JoinRestriction (Maybe a) (Maybe b)] -- ^ Join restrictions+ -> Relation (pa, pb) (Maybe a, Maybe b) -- ^ Result joined relation+full' = join' queryMaybe' queryMaybe'++-- | Basic direct join operation.+join_ :: (qa -> QuerySimple (Record Flat a))+ -> (qb -> QuerySimple (Record Flat b))+ -> qa+ -> qb+ -> [JoinRestriction a b]+ -> Relation () (a, b)+join_ qL qR r0 r1 rs = relation $ do+ pj0 <- qL r0+ pj1 <- qR r1+ sequence_ [ on $ f pj0 pj1 | f <- rs ]+ return $ (,) |$| pj0 |*| pj1++-- | Direct inner join.+inner :: Relation () a -- ^ Left query to join+ -> Relation () b -- ^ Right query to join+ -> [JoinRestriction a b] -- ^ Join restrictions+ -> Relation () (a, b) -- ^ Result joined relation+inner = join_ query query++-- | Direct left outer join.+left :: Relation () a -- ^ Left query to join+ -> Relation () b -- ^ Right query to join+ -> [JoinRestriction a (Maybe b)] -- ^ Join restrictions+ -> Relation () (a, Maybe b) -- ^ Result joined relation+left = join_ query queryMaybe++-- | Direct right outer join.+right :: Relation () a -- ^ Left query to join+ -> Relation () b -- ^ Right query to join+ -> [JoinRestriction (Maybe a) b] -- ^ Join restrictions+ -> Relation () (Maybe a, b) -- ^ Result joined relation+right = join_ queryMaybe query++-- | Direct full outer join.+full :: Relation () a -- ^ Left query to join+ -> Relation () b -- ^ Right query to join+ -> [JoinRestriction (Maybe a) (Maybe b)] -- ^ Join restrictions+ -> Relation () (Maybe a, Maybe b) -- ^ Result joined relation+full = join_ queryMaybe queryMaybe++-- | Apply restriction for direct join style.+on' :: ([JoinRestriction a b] -> Relation pc (a, b))+ -> [JoinRestriction a b]+ -> Relation pc (a, b)+on' = ($)++infixl 8 `inner'`, `left'`, `right'`, `full'`, `inner`, `left`, `right`, `full`, `on'`++unsafeLiftAppend :: (SubQuery -> SubQuery -> SubQuery)+ -> Relation p a+ -> Relation q a+ -> Relation r a+unsafeLiftAppend op a0 a1 = unsafeTypeRelation $ do+ s0 <- untypeRelation a0+ s1 <- untypeRelation a1+ return $ s0 `op` s1++liftAppend :: (SubQuery -> SubQuery -> SubQuery)+ -> Relation () a+ -> Relation () a+ -> Relation () a+liftAppend = unsafeLiftAppend++-- | Union of two relations.+union :: Relation () a -> Relation () a -> Relation () a+union = liftAppend $ Syntax.union Distinct++-- | Union of two relations. Not distinct.+unionAll :: Relation () a -> Relation () a -> Relation () a+unionAll = liftAppend $ Syntax.union All++-- | Subtraction of two relations.+except :: Relation () a -> Relation () a -> Relation () a+except = liftAppend $ Syntax.except Distinct++-- | Subtraction of two relations. Not distinct.+exceptAll :: Relation () a -> Relation () a -> Relation () a+exceptAll = liftAppend $ Syntax.except All++-- | Intersection of two relations.+intersect :: Relation () a -> Relation () a -> Relation () a+intersect = liftAppend $ Syntax.intersect Distinct++-- | Intersection of two relations. Not distinct.+intersectAll :: Relation () a -> Relation () a -> Relation () a+intersectAll = liftAppend $ Syntax.intersect All++liftAppend' :: (SubQuery -> SubQuery -> SubQuery)+ -> Relation p a+ -> Relation q a+ -> Relation (p, q) a+liftAppend' = unsafeLiftAppend++-- | Union of two relations with place-holder parameters.+union' :: Relation p a -> Relation q a -> Relation (p, q) a+union' = liftAppend' $ Syntax.union Distinct++-- | Union of two relations with place-holder parameters. Not distinct.+unionAll' :: Relation p a -> Relation q a -> Relation (p, q) a+unionAll' = liftAppend' $ Syntax.union All++-- | Subtraction of two relations with place-holder parameters.+except' :: Relation p a -> Relation q a -> Relation (p, q) a+except' = liftAppend' $ Syntax.except Distinct++-- | Subtraction of two relations with place-holder parameters. Not distinct.+exceptAll' :: Relation p a -> Relation q a -> Relation (p, q) a+exceptAll' = liftAppend' $ Syntax.except All++-- | Intersection of two relations with place-holder parameters.+intersect' :: Relation p a -> Relation q a -> Relation (p, q) a+intersect' = liftAppend' $ Syntax.intersect Distinct++-- | Intersection of two relations with place-holder parameters. Not distinct.+intersectAll' :: Relation p a -> Relation q a -> Relation (p, q) a+intersectAll' = liftAppend' $ Syntax.intersect All++infixl 7 `union`, `except`, `unionAll`, `exceptAll`+infixl 8 `intersect`, `intersectAll`+infixl 7 `union'`, `except'`, `unionAll'`, `exceptAll'`+infixl 8 `intersect'`, `intersectAll'`
+ src/Database/Relational/SimpleSql.hs view
@@ -0,0 +1,106 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module : Database.Relational.SimpleSql+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines functions to generate simple SQL strings.+module Database.Relational.SimpleSql (+ -- * Query suffix+ QuerySuffix, showsQuerySuffix,++ -- * Update SQL+ updatePrefixSQL,+ updateOtherThanKeySQL,++ -- * Insert SQL+ insertPrefixSQL,++ -- * Delete SQL+ deletePrefixSQL+ ) where++import Data.Array (listArray, (!))+import Data.Monoid (mconcat, (<>))++import Language.SQL.Keyword (Keyword(..), (.=.), (|*|))+import qualified Language.SQL.Keyword as SQL+import Database.Record.ToSql (untypedUpdateValuesIndex)++import Database.Relational.Internal.String+ (StringSQL, stringSQL, showStringSQL, rowConsStringSQL, )++import Database.Relational.Pi (Pi)+import qualified Database.Relational.Pi.Unsafe as UnsafePi+import Database.Relational.Table (Table, name, columns, recordWidth)+import qualified Database.Relational.Record as Record+++-- | Type for query suffix words+type QuerySuffix = [Keyword]++-- | Expand query suffix words+showsQuerySuffix :: QuerySuffix -> StringSQL+showsQuerySuffix = mconcat++-- | Generate prefix string of update SQL.+updatePrefixSQL :: Table r -> StringSQL+updatePrefixSQL table = UPDATE <> stringSQL (name table)++-- | Generate update SQL by specified key and table.+-- Columns name list of table are also required.+updateSQL' :: String -- ^ Table name+ -> [StringSQL] -- ^ Column name list to update+ -> [StringSQL] -- ^ Key column name list+ -> String -- ^ Result SQL+updateSQL' table cols key =+ showStringSQL $ mconcat+ [UPDATE, stringSQL table, SET, SQL.fold (|*|) updAssigns,+ WHERE, SQL.fold SQL.and keyAssigns]+ where+ assigns cs = [ c .=. "?" | c <- cs ]+ updAssigns = assigns cols+ keyAssigns = assigns key++-- | Generate update SQL by specified key and table.+-- Columns name list of table are also required.+updateOtherThanKeySQL' :: String -- ^ Table name+ -> [StringSQL] -- ^ Column name list+ -> [Int] -- ^ Key column indexes+ -> String -- ^ Result SQL+updateOtherThanKeySQL' table cols ixs =+ updateSQL' table updColumns keyColumns+ where+ width' = length cols+ cols' = listArray (0, width' -1) cols+ otherThanKey = untypedUpdateValuesIndex ixs width'+ columns' is = [ cols' ! i | i <- is ]+ updColumns = columns' otherThanKey+ keyColumns = columns' ixs++-- | Generate update SQL specified by single key.+updateOtherThanKeySQL :: Table r -- ^ Table metadata+ -> Pi r p -- ^ Key columns+ -> String -- ^ Result SQL+updateOtherThanKeySQL tbl key =+ updateOtherThanKeySQL' (name tbl) (columns tbl) (UnsafePi.unsafeExpandIndexes' (recordWidth tbl) key)++-- | Generate prefix string of insert SQL.+insertPrefixSQL :: Pi r r' -> Table r -> StringSQL+insertPrefixSQL pi' table =+ INSERT <> INTO <> stringSQL (name table) <> rowConsStringSQL cols where+ cols = Record.columns . Record.wpi (recordWidth table) (Record.unsafeFromTable table) $ pi'++-- | Generate all column delete SQL by specified table. Untyped table version.+deletePrefixSQL' :: String -> StringSQL+deletePrefixSQL' table = DELETE <> FROM <> stringSQL table++-- | Generate all column delete SQL by specified table.+deletePrefixSQL :: Table r -- ^ Table metadata+ -> StringSQL -- ^ Result SQL+deletePrefixSQL = deletePrefixSQL' . name
+ src/Database/Relational/SqlSyntax.hs view
@@ -0,0 +1,25 @@+-- |+-- Module : Database.Relational.SqlSyntax+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module is integrated module of sql-syntax.+module Database.Relational.SqlSyntax (+ module Database.Relational.SqlSyntax.Types,+ module Database.Relational.SqlSyntax.Join,+ module Database.Relational.SqlSyntax.Aggregate,+ module Database.Relational.SqlSyntax.Query,+ module Database.Relational.SqlSyntax.Fold,+ module Database.Relational.SqlSyntax.Updates,+ ) where++import Database.Relational.SqlSyntax.Types+import Database.Relational.SqlSyntax.Join (growProduct, restrictProduct, )+import Database.Relational.SqlSyntax.Aggregate+import Database.Relational.SqlSyntax.Query+import Database.Relational.SqlSyntax.Fold+import Database.Relational.SqlSyntax.Updates
+ src/Database/Relational/SqlSyntax/Aggregate.hs view
@@ -0,0 +1,94 @@+-- |+-- Module : Database.Relational.SqlSyntax.Aggregate+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides grouping-sets structure of SQL syntax tree.+module Database.Relational.SqlSyntax.Aggregate (+ aggregateColumnRef,+ aggregatePowerKey, aggregateGroupingSet,+ aggregateRollup, aggregateCube, aggregateSets,++ composeGroupBy, composePartitionBy,++ aggregateKeyRecord, aggregateKeyElement, unsafeAggregateKey,+ ) where++import Data.Monoid (Monoid (..), (<>))++import Language.SQL.Keyword (Keyword(..), (|*|))+import qualified Language.SQL.Keyword as SQL++import Database.Relational.Internal.String (StringSQL)+import Database.Relational.SqlSyntax.Types+ (AggregateBitKey (..), AggregateSet (..), AggregateElem (..),+ AggregateColumnRef, AggregateKey (..), )+++-- | Single term aggregation element.+aggregateColumnRef :: AggregateColumnRef -> AggregateElem+aggregateColumnRef = ColumnRef++-- | Key of aggregation power set.+aggregatePowerKey :: [AggregateColumnRef] -> AggregateBitKey+aggregatePowerKey = AggregateBitKey++-- | Single grouping set.+aggregateGroupingSet :: [AggregateElem] -> AggregateSet+aggregateGroupingSet = AggregateSet++-- | Rollup aggregation element.+aggregateRollup :: [AggregateBitKey] -> AggregateElem+aggregateRollup = Rollup++-- | Cube aggregation element.+aggregateCube :: [AggregateBitKey] -> AggregateElem+aggregateCube = Cube++-- | Grouping sets aggregation.+aggregateSets :: [AggregateSet] -> AggregateElem+aggregateSets = GroupingSets++commaed :: [StringSQL] -> StringSQL+commaed = SQL.fold (|*|)++pComma :: (a -> StringSQL) -> [a] -> StringSQL+pComma qshow = SQL.paren . commaed . map qshow++showsAggregateBitKey :: AggregateBitKey -> StringSQL+showsAggregateBitKey (AggregateBitKey ts) = pComma id ts++-- | Compose GROUP BY clause from AggregateElem list.+composeGroupBy :: [AggregateElem] -> StringSQL+composeGroupBy = d where+ d [] = mempty+ d es@(_:_) = GROUP <> BY <> rec es+ keyList op ss = op <> pComma showsAggregateBitKey ss+ rec = commaed . map showsE+ showsGs (AggregateSet s) = SQL.paren $ rec s+ showsE (ColumnRef t) = t+ showsE (Rollup ss) = keyList ROLLUP ss+ showsE (Cube ss) = keyList CUBE ss+ showsE (GroupingSets ss) = GROUPING <> SETS <> pComma showsGs ss++-- | Compose PARTITION BY clause from AggregateColumnRef list.+composePartitionBy :: [AggregateColumnRef] -> StringSQL+composePartitionBy = d where+ d [] = mempty+ d ts@(_:_) = PARTITION <> BY <> commaed ts++-- | Extract typed record from 'AggregateKey'.+aggregateKeyRecord :: AggregateKey a -> a+aggregateKeyRecord (AggregateKey (p, _c)) = p++-- | Extract untyped term from 'AggregateKey'.+aggregateKeyElement :: AggregateKey a -> AggregateElem+aggregateKeyElement (AggregateKey (_p, c)) = c++-- | Unsafely bind typed-record and untyped-term into 'AggregateKey'.+unsafeAggregateKey :: (a, AggregateElem) -> AggregateKey a+unsafeAggregateKey = AggregateKey
+ src/Database/Relational/SqlSyntax/Fold.hs view
@@ -0,0 +1,270 @@+{-# LANGUAGE OverloadedStrings #-}++-- |+-- Module : Database.Relational.SqlSyntax.Fold+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines sub-query structure used in query products.+module Database.Relational.SqlSyntax.Fold (+ -- * Sub-query+ showSQL, toSQL, unitSQL, width,++ -- * Qualified Sub-query+ queryWidth,++ -- * Sub-query columns+ column,++ -- * Tuple and Record+ tupleFromJoinedSubQuery,++ recordRawColumns,++ -- * Query restriction+ composeWhere, composeHaving+ ) where++import Control.Applicative ((<$>), pure)+import Data.Monoid (mempty, (<>), mconcat)+import Data.Traversable (traverse)++import Language.SQL.Keyword (Keyword(..), (|*|))+import qualified Language.SQL.Keyword as SQL++import Database.Relational.Internal.ContextType (Flat, Aggregated)+import Database.Relational.Internal.Config+ (Config (productUnitSupport), ProductUnitSupport (PUSupported, PUNotSupported), )+import Database.Relational.Internal.UntypedTable ((!))+import qualified Database.Relational.Internal.UntypedTable as UntypedTable+import Database.Relational.Internal.String+ (StringSQL, stringSQL, rowStringSQL, showStringSQL, boolSQL, )+import Database.Relational.SqlSyntax.Query (composeOrderBy, )+import Database.Relational.SqlSyntax.Aggregate (composeGroupBy, )+import Database.Relational.SqlSyntax.Types+ (SubQuery (..), Record, Tuple, Predicate,+ Column (..), CaseClause(..), WhenClauses (..),+ NodeAttr (Just', Maybe), ProductTree (Leaf, Join), JoinProduct,+ Duplication (..), SetOp (..), BinOp (..), Qualifier (..), Qualified (..), )+import qualified Database.Relational.SqlSyntax.Types as Syntax+++-- | Compose duplication attribute string.+showsDuplication :: Duplication -> StringSQL+showsDuplication = dup where+ dup All = ALL+ dup Distinct = DISTINCT++showsSetOp' :: SetOp -> StringSQL+showsSetOp' = d where+ d Union = UNION+ d Except = EXCEPT+ d Intersect = INTERSECT++showsSetOp :: SetOp -> Duplication -> StringSQL+showsSetOp op dup0 = showsSetOp' op <> mayDup dup0 where+ mayDup dup@All = showsDuplication dup+ mayDup Distinct = mempty++-- | Alias string from qualifier+showQualifier :: Qualifier -> StringSQL+showQualifier (Qualifier i) = stringSQL $ 'T' : show i++-- | Binary operator to qualify.+(<.>) :: Qualifier -> StringSQL -> StringSQL+i <.> n = showQualifier i SQL.<.> n++columnN :: Int -> StringSQL+columnN i = stringSQL $ 'f' : show i++asColumnN :: StringSQL -> Int -> StringSQL+c `asColumnN` n =c `SQL.as` columnN n++-- | Qualified expression from qualifier and projection index.+columnFromId :: Qualifier -> Int -> StringSQL+columnFromId qi i = qi <.> columnN i++-- | From 'Qualified' SQL string into qualified formed 'String'+-- like (SELECT ...) AS T<n>+qualifiedSQLas :: Qualified StringSQL -> StringSQL+qualifiedSQLas q = Syntax.unQualify q <> showQualifier (Syntax.qualifier q)++-- | Width of 'SubQuery'.+width :: SubQuery -> Int+width = d where+ d (Table u) = UntypedTable.width' u+ d (Bin _ l _) = width l+ d (Flat _ up _ _ _ _) = Syntax.tupleWidth up+ d (Aggregated _ up _ _ _ _ _ _) = Syntax.tupleWidth up++-- | Width of 'Qualified' 'SubQUery'.+queryWidth :: Qualified SubQuery -> Int+queryWidth = width . Syntax.unQualify++-- | Generate SQL from table for top-level.+fromTableToSQL :: UntypedTable.Untyped -> StringSQL+fromTableToSQL t =+ SELECT <> SQL.fold (|*|) (UntypedTable.columns' t) <>+ FROM <> stringSQL (UntypedTable.name' t)++-- | Generate normalized column SQL from table.+fromTableToNormalizedSQL :: UntypedTable.Untyped -> StringSQL+fromTableToNormalizedSQL t = SELECT <> SQL.fold (|*|) columns' <>+ FROM <> stringSQL (UntypedTable.name' t) where+ columns' = zipWith asColumnN+ (UntypedTable.columns' t)+ [(0 :: Int)..]++-- | Generate normalized column SQL from joined tuple.+selectPrefixSQL :: Tuple -> Duplication -> StringSQL+selectPrefixSQL up da = SELECT <> showsDuplication da <>+ SQL.fold (|*|) columns' where+ columns' = zipWith asColumnN+ (map showColumn up)+ [(0 :: Int)..]++-- | Normalized column SQL for union like operations+-- to keep compatibility with engines like Sqlite and MySQL.+-- SQL with no ordering term is not paren-ed.+normalizedSQL :: SubQuery -> StringSQL+normalizedSQL = d where+ d (Table t) = fromTableToNormalizedSQL t+ d sub@(Bin {}) = showUnitSQL sub+ d sub@(Flat _ _ _ _ _ ots)+ | null ots = showSQL sub+ | otherwise = showUnitSQL sub+ d sub@(Aggregated _ _ _ _ _ _ _ ots)+ | null ots = showSQL sub+ | otherwise = showUnitSQL sub++-- | SQL string for nested-query and toplevel-SQL.+toSQLs :: SubQuery+ -> (StringSQL, StringSQL) -- ^ sub-query SQL and top-level SQL+toSQLs = d where+ d (Table u) = (stringSQL $ UntypedTable.name' u, fromTableToSQL u)+ d (Bin (BinOp (op, da)) l r) = (SQL.paren q, q) where+ q = mconcat [normalizedSQL l, showsSetOp op da, normalizedSQL r]+ d (Flat cf up da pd rs od) = (SQL.paren q, q) where+ q = selectPrefixSQL up da <> showsJoinProduct (productUnitSupport cf) pd <> composeWhere rs+ <> composeOrderBy od+ d (Aggregated cf up da pd rs ag grs od) = (SQL.paren q, q) where+ q = selectPrefixSQL up da <> showsJoinProduct (productUnitSupport cf) pd <> composeWhere rs+ <> composeGroupBy ag <> composeHaving grs <> composeOrderBy od++showUnitSQL :: SubQuery -> StringSQL+showUnitSQL = fst . toSQLs++-- | SQL string for nested-qeury.+unitSQL :: SubQuery -> String+unitSQL = showStringSQL . showUnitSQL++-- | SQL StringSQL for toplevel-SQL.+showSQL :: SubQuery -> StringSQL+showSQL = snd . toSQLs++-- | SQL string for toplevel-SQL.+toSQL :: SubQuery -> String+toSQL = showStringSQL . showSQL++-- | Get column SQL string of 'Qualified' 'SubQuery'.+column :: Qualified SubQuery -> Int -> StringSQL+column qs = d (Syntax.unQualify qs) where+ q = Syntax.qualifier qs+ d (Table u) i = q <.> (u ! i)+ d (Bin {}) i = q `columnFromId` i+ d (Flat _ up _ _ _ _) i = showTupleIndex up i+ d (Aggregated _ up _ _ _ _ _ _) i = showTupleIndex up i++-- | Make untyped tuple (qualified column list) from joined sub-query ('Qualified' 'SubQuery').+tupleFromJoinedSubQuery :: Qualified SubQuery -> Tuple+tupleFromJoinedSubQuery qs = d $ Syntax.unQualify qs where+ normalized = SubQueryRef <$> traverse (\q -> [0 .. width q - 1]) qs+ d (Table _) = map RawColumn . map (column qs)+ $ take (queryWidth qs) [0..]+ d (Bin {}) = normalized+ d (Flat {}) = normalized+ d (Aggregated {}) = normalized++-- | index result of each when clause and else clause.+indexWhensClause :: WhenClauses -> Int -> StringSQL+indexWhensClause (WhenClauses ps e) i =+ mconcat [ when' p r | (p, r) <- ps] <> else' <> SQL.END+ where+ when' p r = SQL.WHEN <> rowStringSQL (map showColumn p) <>+ SQL.THEN <> showTupleIndex r i+ else' = SQL.ELSE <> showTupleIndex e i++-- | index result of each when clause and else clause.+caseClause :: CaseClause -> Int -> StringSQL+caseClause c i = d c where+ d (CaseSearch wcl) = SQL.CASE <> indexWhensClause wcl i+ d (CaseSimple m wcl) = SQL.CASE <> rowStringSQL (map showColumn m) <> indexWhensClause wcl i++-- | Convert from typed' Column' into column string expression.+showColumn :: Column -> StringSQL+showColumn = d where+ d (RawColumn e) = e+ d (SubQueryRef qi) = Syntax.qualifier qi `columnFromId` Syntax.unQualify qi+ d (Scalar sub) = showUnitSQL sub+ d (Case c i) = caseClause c i++-- | Get column SQL string of 'Tuple'.+showTupleIndex :: Tuple -- ^ Source 'Tuple'+ -> Int -- ^ Column index+ -> StringSQL -- ^ Result SQL string+showTupleIndex up i+ | 0 <= i && i < Syntax.tupleWidth up =+ showColumn $ up !! i+ | otherwise =+ error $ "showTupleIndex: index out of bounds: " ++ show i++-- | Get column SQL string list of record.+recordRawColumns :: Record c r -- ^ Source 'Record'+ -> [StringSQL] -- ^ Result SQL string list+recordRawColumns = map showColumn . Syntax.untypeRecord+++-- | Show product tree of query into SQL. StringSQL result.+showsQueryProduct :: ProductTree [Predicate Flat] -> StringSQL+showsQueryProduct = rec where+ joinType Just' Just' = INNER+ joinType Just' Maybe = LEFT+ joinType Maybe Just' = RIGHT+ joinType Maybe Maybe = FULL+ urec n = case Syntax.nodeTree n of+ p@(Leaf _) -> rec p+ p@(Join {}) -> SQL.paren (rec p)+ rec (Leaf q) = qualifiedSQLas $ fmap showUnitSQL q+ rec (Join left' right' rs) =+ mconcat+ [urec left',+ joinType (Syntax.nodeAttr left') (Syntax.nodeAttr right'), JOIN,+ urec right',+ ON, foldr1 SQL.and $ ps ++ concat [ pure $ boolSQL True | null ps ] ]+ where ps = [ rowStringSQL $ recordRawColumns p | p <- rs ]++-- | Shows join product of query.+showsJoinProduct :: ProductUnitSupport -> JoinProduct -> StringSQL+showsJoinProduct ups = maybe (up ups) from where+ from qp = FROM <> showsQueryProduct qp+ up PUSupported = mempty+ up PUNotSupported = error "relation: Unit product support mode is disabled!"+++-- | Compose SQL String from 'QueryRestriction'.+composeRestrict :: Keyword -> [Predicate c] -> StringSQL+composeRestrict k = d where+ d [] = mempty+ d ps@(_:_) = k <> foldr1 SQL.and [ rowStringSQL $ recordRawColumns p | p <- ps ]++-- | Compose WHERE clause from 'QueryRestriction'.+composeWhere :: [Predicate Flat] -> StringSQL+composeWhere = composeRestrict WHERE++-- | Compose HAVING clause from 'QueryRestriction'.+composeHaving :: [Predicate Aggregated] -> StringSQL+composeHaving = composeRestrict HAVING
+ src/Database/Relational/SqlSyntax/Join.hs view
@@ -0,0 +1,54 @@+-- |+-- Module : Database.Relational.SqlSyntax.Join+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines product structure to compose SQL join.+module Database.Relational.SqlSyntax.Join (+ -- * Interfaces to manipulate ProductTree type+ growProduct, restrictProduct,+ ) where++import Prelude hiding (and, product)+import Control.Applicative (pure)+import Data.Monoid ((<>), mempty)+import Data.DList (DList)++import Database.Relational.Internal.ContextType (Flat)+import Database.Relational.SqlSyntax.Types+ (NodeAttr (..), ProductTree (..), Node (..), Qualified, SubQuery,+ Predicate)+++-- | Push new tree into product right term.+growRight :: Maybe (Node (DList (Predicate Flat))) -- ^ Current tree+ -> (NodeAttr, ProductTree (DList (Predicate Flat))) -- ^ New tree to push into right+ -> Node (DList (Predicate Flat)) -- ^ Result node+growRight = d where+ d Nothing (naR, q) = Node naR q+ d (Just l) (naR, q) = Node Just' $ Join l (Node naR q) mempty++-- | Push new leaf node into product right term.+growProduct :: Maybe (Node (DList (Predicate Flat))) -- ^ Current tree+ -> (NodeAttr, Qualified SubQuery) -- ^ New leaf to push into right+ -> Node (DList (Predicate Flat)) -- ^ Result node+growProduct = match where+ match t (na, q) = growRight t (na, Leaf q)++-- | Add restriction into top product of product tree.+restrictProduct' :: ProductTree (DList (Predicate Flat)) -- ^ Product to restrict+ -> Predicate Flat -- ^ Restriction to add+ -> ProductTree (DList (Predicate Flat)) -- ^ Result product+restrictProduct' = d where+ d (Join lp rp rs) rs' = Join lp rp (rs <> pure rs')+ d leaf'@(Leaf _) _ = leaf' -- or error on compile++-- | Add restriction into top product of product tree node.+restrictProduct :: Node (DList (Predicate Flat)) -- ^ Target node which has product to restrict+ -> Predicate Flat -- ^ Restriction to add+ -> Node (DList (Predicate Flat)) -- ^ Result node+restrictProduct (Node a t) e = Node a (restrictProduct' t e)
+ src/Database/Relational/SqlSyntax/Query.hs view
@@ -0,0 +1,114 @@+-- |+-- Module : Database.Relational.SqlSyntax.Query+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides building and expanding operations of SQL query tree.+module Database.Relational.SqlSyntax.Query (+ flatSubQuery, aggregatedSubQuery,+ union, except, intersect,+ caseSearch, case',++ composeOrderBy,+ ) where++import Data.Monoid (mempty, (<>))++import Language.SQL.Keyword (Keyword(..), (|*|))+import qualified Language.SQL.Keyword as SQL++import Database.Relational.Internal.Config (Config)+import Database.Relational.Internal.ContextType (Flat, Aggregated)+import Database.Relational.Internal.String (StringSQL)+import Database.Relational.SqlSyntax.Types+ (Duplication (..), SetOp (..), BinOp (..),+ Order (..), Nulls (..), OrderingTerm, AggregateElem,+ JoinProduct, Predicate, WhenClauses (..), CaseClause (..), SubQuery (..),+ Column (..), Tuple, Record, record, untypeRecord, recordWidth, )+++-- | Unsafely generate flat 'SubQuery' from untyped components.+flatSubQuery :: Config+ -> Tuple+ -> Duplication+ -> JoinProduct+ -> [Predicate Flat]+ -> [OrderingTerm]+ -> SubQuery+flatSubQuery = Flat++-- | Unsafely generate aggregated 'SubQuery' from untyped components.+aggregatedSubQuery :: Config+ -> Tuple+ -> Duplication+ -> JoinProduct+ -> [Predicate Flat]+ -> [AggregateElem]+ -> [Predicate Aggregated]+ -> [OrderingTerm]+ -> SubQuery+aggregatedSubQuery = Aggregated++setBin :: SetOp -> Duplication -> SubQuery -> SubQuery -> SubQuery+setBin op = Bin . BinOp . (,) op++-- | Union binary operator on 'SubQuery'+union :: Duplication -> SubQuery -> SubQuery -> SubQuery+union = setBin Union++-- | Except binary operator on 'SubQuery'+except :: Duplication -> SubQuery -> SubQuery -> SubQuery+except = setBin Except++-- | Intersect binary operator on 'SubQuery'+intersect :: Duplication -> SubQuery -> SubQuery -> SubQuery+intersect = setBin Intersect+++whenClauses :: String -- ^ Error tag+ -> [(Record c a, Record c b)] -- ^ Each when clauses+ -> Record c b -- ^ Else result record+ -> WhenClauses -- ^ Result clause+whenClauses eTag ws0 e = d ws0+ where+ d [] = error $ eTag ++ ": Empty when clauses!"+ d ws@(_:_) =+ WhenClauses [ (untypeRecord p, untypeRecord r) | (p, r) <- ws ]+ $ untypeRecord e++-- | Search case operator correnponding SQL search /CASE/.+-- Like, /CASE WHEN p0 THEN a WHEN p1 THEN b ... ELSE c END/+caseSearch :: [(Predicate c, Record c a)] -- ^ Each when clauses+ -> Record c a -- ^ Else result record+ -> Record c a -- ^ Result record+caseSearch ws e =+ record [ Case c i | i <- [0 .. recordWidth e - 1] ]+ where+ c = CaseSearch $ whenClauses "caseSearch" ws e++-- | Simple case operator correnponding SQL simple /CASE/.+-- Like, /CASE x WHEN v THEN a WHEN w THEN b ... ELSE c END/+case' :: Record c a -- ^ Record value to match+ -> [(Record c a, Record c b)] -- ^ Each when clauses+ -> Record c b -- ^ Else result record+ -> Record c b -- ^ Result record+case' v ws e =+ record [ Case c i | i <- [0 .. recordWidth e - 1] ]+ where+ c = CaseSimple (untypeRecord v) $ whenClauses "case'" ws e+++-- | Compose ORDER BY clause from OrderingTerms+composeOrderBy :: [OrderingTerm] -> StringSQL+composeOrderBy = d where+ d [] = mempty+ d ts@(_:_) = ORDER <> BY <> SQL.fold (|*|) (map showsOt ts)+ showsOt ((o, mn), e) = e <> order o <> maybe mempty ((NULLS <>) . nulls) mn+ order Asc = ASC+ order Desc = DESC+ nulls NullsFirst = FIRST+ nulls NullsLast = LAST
+ src/Database/Relational/SqlSyntax/Types.hs view
@@ -0,0 +1,210 @@+{-# LANGUAGE DeriveFunctor, DeriveFoldable, DeriveTraversable #-}++-- |+-- Module : Database.Relational.SqlSyntax.Types+-- Copyright : 2015-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines sub-query structure used in query products.+module Database.Relational.SqlSyntax.Types (+ -- * The SubQuery+ SubQuery (..),++ -- * Set operations+ Duplication (..), SetOp (..), BinOp (..),++ -- * Qualifiers for nested query+ Qualifier (..), Qualified (..), qualifier, unQualify, qualify,++ -- * Ordering types+ Order (..), Nulls (..), OrderColumn, OrderingTerm,++ -- * Aggregating types+ AggregateColumnRef,+ AggregateBitKey (..), AggregateSet (..), AggregateElem (..),++ AggregateKey (..),++ -- * Product tree type+ NodeAttr (..), ProductTree (..),+ Node (..), nodeAttr, nodeTree,+ JoinProduct,++ -- * Case+ CaseClause (..), WhenClauses(..),++ -- * Column, Tuple, Record and Projection+ Column (..), Tuple, tupleWidth,+ Record, untypeRecord, record, PI,+ recordWidth,+ typeFromRawColumns,+ typeFromScalarSubQuery,++ -- * Predicate to restrict Query result+ Predicate,+ ) where++import Prelude hiding (and, product)+import Data.Foldable (Foldable)+import Data.Traversable (Traversable)++import Database.Relational.Internal.Config (Config)+import Database.Relational.Internal.ContextType (Flat, Aggregated)+import Database.Relational.Internal.String (StringSQL)+import Database.Relational.Internal.UntypedTable (Untyped)+++-- | Result record duplication attribute+data Duplication = All | Distinct deriving Show++-- | Set operators+data SetOp = Union | Except | Intersect deriving Show++-- | Set binary operators+newtype BinOp = BinOp (SetOp, Duplication) deriving Show++-- | Order direction. Ascendant or Descendant.+data Order = Asc | Desc deriving Show++-- | Order of null.+data Nulls = NullsFirst | NullsLast deriving Show++-- | Type for order-by column+type OrderColumn = StringSQL++-- | Type for order-by term+type OrderingTerm = ((Order, Maybe Nulls), OrderColumn)++-- | Type for group-by term+type AggregateColumnRef = StringSQL++-- | Type for group key.+newtype AggregateBitKey = AggregateBitKey [AggregateColumnRef] deriving Show++-- | Type for grouping set+newtype AggregateSet = AggregateSet [AggregateElem] deriving Show++-- | Type for group-by tree+data AggregateElem = ColumnRef AggregateColumnRef+ | Rollup [AggregateBitKey]+ | Cube [AggregateBitKey]+ | GroupingSets [AggregateSet]+ deriving Show++-- | Typeful aggregate element.+newtype AggregateKey a = AggregateKey (a, AggregateElem)++-- | Sub-query type+data SubQuery = Table Untyped+ | Flat Config+ Tuple Duplication JoinProduct [Predicate Flat]+ [OrderingTerm]+ | Aggregated Config+ Tuple Duplication JoinProduct [Predicate Flat]+ [AggregateElem] [Predicate Aggregated] [OrderingTerm]+ | Bin BinOp SubQuery SubQuery+ deriving Show++-- | Qualifier type.+newtype Qualifier = Qualifier Int deriving Show++-- | Qualified query.+data Qualified a =+ Qualified Qualifier a+ deriving (Show, Functor, Foldable, Traversable)++-- | Get qualifier+qualifier :: Qualified a -> Qualifier+qualifier (Qualified q _) = q++-- | Unqualify.+unQualify :: Qualified a -> a+unQualify (Qualified _ a) = a++-- | Add qualifier+qualify :: Qualifier -> a -> Qualified a+qualify = Qualified+++-- | node attribute for product.+data NodeAttr = Just' | Maybe deriving Show++type QS = Qualified SubQuery++-- | Product tree type. Product tree is constructed by left node and right node.+data ProductTree rs+ = Leaf QS+ | Join !(Node rs) !(Node rs) !rs+ deriving (Show, Functor)++-- | Product node. node attribute and product tree.+data Node rs = Node !NodeAttr !(ProductTree rs) deriving (Show, Functor)++-- | Get node attribute.+nodeAttr :: Node rs -> NodeAttr+nodeAttr (Node a _) = a where++-- | Get tree from node.+nodeTree :: Node rs -> ProductTree rs+nodeTree (Node _ t) = t++-- | Type for join product of query.+type JoinProduct = Maybe (ProductTree [Predicate Flat])++-- | when clauses+data WhenClauses =+ WhenClauses [(Tuple, Tuple)] Tuple+ deriving Show++-- | case clause+data CaseClause+ = CaseSearch WhenClauses+ | CaseSimple Tuple WhenClauses+ deriving Show++-- | Projected column structure unit with single column width+data Column+ = RawColumn StringSQL -- ^ used in immediate value or unsafe operations+ | SubQueryRef (Qualified Int) -- ^ normalized sub-query reference T<n> with Int index+ | Scalar SubQuery -- ^ scalar sub-query+ | Case CaseClause Int -- ^ <n>th column of case clause+ deriving Show++-- | Untyped projected tuple. Forgot record type.+type Tuple = [Column]++-- | Width of 'Tuple'.+tupleWidth :: Tuple -> Int+tupleWidth = length++-- | Phantom typed record. Projected into Haskell record type 't'.+newtype Record c t =+ Record+ { untypeRecord :: Tuple {- ^ Discard record type -} } deriving Show++-- | Type for predicate to restrict of query result.+type Predicate c = Record c (Maybe Bool)++-- | Type for projection function.+type PI c a b = Record c a -> Record c b++-- | Unsafely type 'Tuple' value to 'Record' type.+record :: Tuple -> Record c t+record = Record++-- | Width of 'Record'.+recordWidth :: Record c r -> Int+recordWidth = length . untypeRecord++-- | Unsafely generate 'Record' from SQL string list.+typeFromRawColumns :: [StringSQL] -- ^ SQL string list specifies columns+ -> Record c r -- ^ Result 'Record'+typeFromRawColumns = record . map RawColumn++-- | Unsafely generate 'Record' from scalar sub-query.+typeFromScalarSubQuery :: SubQuery -> Record c t+typeFromScalarSubQuery = record . (:[]) . Scalar
+ src/Database/Relational/SqlSyntax/Updates.hs view
@@ -0,0 +1,63 @@+-- |+-- Module : Database.Relational.SqlSyntax.Updates+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module provides types and expanding operations of SQL update and insert structure.+module Database.Relational.SqlSyntax.Updates (+ -- * Update and Insert assignments+ AssignColumn, AssignTerm, Assignment,++ composeSets,+ composeChunkValues, composeChunkValuesWithColumns,+ ) where++import Data.Monoid ((<>))++import Language.SQL.Keyword (Keyword(..), (|*|), (.=.))+import qualified Language.SQL.Keyword as SQL++import Database.Relational.Internal.String (StringSQL, rowConsStringSQL)+++-- | Column SQL String of assignment+type AssignColumn = StringSQL++-- | Value SQL String of assignment+type AssignTerm = StringSQL++-- | Assignment pair+type Assignment = (AssignColumn, AssignTerm)++-- | Compose SET clause from ['Assignment'].+composeSets :: [Assignment] -> StringSQL+composeSets as = assigns where+ assignList = foldr (\ (col, term) r ->+ (col .=. term) : r)+ [] as+ assigns | null assignList = error "Update assignment list is null!"+ | otherwise = SET <> SQL.fold (|*|) assignList++-- | Compose VALUES clause from value expression list.+composeChunkValues :: Int -- ^ record count per chunk+ -> [AssignTerm] -- ^ value expression list+ -> Keyword+composeChunkValues n0 vs =+ VALUES <> cvs+ where+ n | n0 >= 1 = n0+ | otherwise = error $ "Invalid record count value: " ++ show n0+ cvs = SQL.fold (|*|) . replicate n $ rowConsStringSQL vs++-- | Compose VALUES clause from value expression list.+composeChunkValuesWithColumns :: Int -- ^ record count per chunk+ -> [Assignment] -- ^+ -> StringSQL+composeChunkValuesWithColumns sz as =+ rowConsStringSQL cs <> composeChunkValues sz vs+ where+ (cs, vs) = unzip as
+ src/Database/Relational/TH.hs view
@@ -0,0 +1,475 @@+{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE MultiParamTypeClasses #-}+{-# LANGUAGE ExplicitForAll #-}+{-# LANGUAGE ParallelListComp #-}++-- |+-- Module : Database.Relational.TH+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines templates for Haskell record type and type class instances+-- to define column projection on SQL query like Haskell records.+-- Templates are generated by also using functions of "Database.Record.TH" module,+-- so mapping between list of untyped SQL type and Haskell record type will be done too.+module Database.Relational.TH (+ -- * All templates about table+ defineTable,++ -- * Inlining typed 'Query'+ unsafeInlineQuery,+ inlineQuery,++ -- * Column projections and basic 'Relation' for Haskell record+ defineTableTypesAndRecord,++ -- * Constraint key templates+ defineHasPrimaryKeyInstance,+ defineHasPrimaryKeyInstanceWithConfig,+ defineHasNotNullKeyInstance,+ defineHasNotNullKeyInstanceWithConfig,+ defineScalarDegree,++ -- * Column projections+ defineColumns, defineColumnsDefault,++ defineTuplePi,++ -- * Table metadata type and basic 'Relation'+ defineTableTypes, defineTableTypesWithConfig,++ -- * Basic SQL templates generate rules+ definePrimaryQuery,+ definePrimaryUpdate,++ -- * Var expression templates+ derivationExpDefault,+ tableVarExpDefault,+ relationVarExp,++ -- * Derived SQL templates from table definitions+ defineSqlsWithPrimaryKey,+ defineSqlsWithPrimaryKeyDefault,++ -- * Reify+ makeRelationalRecordDefault,+ reifyRelation,+ ) where++import Data.Char (toUpper, toLower)+import Data.List (foldl1')+import Data.Array.IArray ((!))+import Data.Functor.ProductIsomorphic.TH+ (reifyRecordType, defineProductConstructor)+import Data.Functor.ProductIsomorphic.Unsafe (ProductConstructor (..))++import Language.Haskell.TH+ (Name, nameBase, Q, reify, Dec, instanceD, ExpQ, stringE, listE,+ TypeQ, Type (AppT, ConT), varT, tupleT, appT, arrowT, classP)+import Language.Haskell.TH.Compat.Reify (unVarI)+import Language.Haskell.TH.Name.CamelCase+ (VarName, varName, ConName (ConName), conName, varNameWithPrefix, varCamelcaseName, toVarExp, toTypeCon)+import Language.Haskell.TH.Lib.Extra (simpleValD, maybeD, integralE)++import Database.Record.TH+ (columnOffsetsVarNameDefault, recordTypeName, recordTemplate,+ defineRecordTypeWithConfig, defineHasColumnConstraintInstance)+import qualified Database.Record.TH as Record++import Database.Relational+ (Table, Pi, id', Relation, ShowConstantTermsSQL,+ NameConfig (..), SchemaNameMode (..), IdentifierQuotation (..),+ Config (normalizedTableName, schemaNameMode, nameConfig, identifierQuotation),+ relationalQuerySQL, Query, relationalQuery, KeyUpdate,+ Insert, derivedInsert, InsertQuery, derivedInsertQuery,+ HasConstraintKey(constraintKey), Primary, NotNull, primary, primaryUpdate)++import Database.Relational.BaseTH (defineTuplePi, defineRecordProjections)+import Database.Relational.Scalar (defineScalarDegree)+import Database.Relational.Constraint (Key, unsafeDefineConstraintKey)+import Database.Relational.Table (TableDerivable (..))+import qualified Database.Relational.Table as Table+import Database.Relational.Relation (derivedRelation)+import Database.Relational.SimpleSql (QuerySuffix)+import Database.Relational.Type (unsafeTypedQuery)+import qualified Database.Relational.Pi.Unsafe as UnsafePi+++-- | Rule template to infer constraint key.+defineHasConstraintKeyInstance :: TypeQ -- ^ Constraint type+ -> TypeQ -- ^ Record type+ -> TypeQ -- ^ Key type+ -> [Int] -- ^ Indexes specifies key+ -> Q [Dec] -- ^ Result 'HasConstraintKey' declaration+defineHasConstraintKeyInstance constraint recType colType indexes = do+ -- kc <- defineHasColumnConstraintInstance constraint recType index+ ck <- [d| instance HasConstraintKey $constraint $recType $colType where+ constraintKey = unsafeDefineConstraintKey $(listE [integralE ix | ix <- indexes])+ |]+ return ck++-- | Rule template to infer primary key.+defineHasPrimaryKeyInstance :: TypeQ -- ^ Record type+ -> TypeQ -- ^ Key type+ -> [Int] -- ^ Indexes specifies key+ -> Q [Dec] -- ^ Result constraint key declarations+defineHasPrimaryKeyInstance recType colType indexes = do+ kc <- Record.defineHasPrimaryKeyInstance recType indexes+ ck <- defineHasConstraintKeyInstance [t| Primary |] recType colType indexes+ return $ kc ++ ck++-- | Rule template to infer primary key.+defineHasPrimaryKeyInstanceWithConfig :: Config -- ^ configuration parameters+ -> String -- ^ Schema name+ -> String -- ^ Table name+ -> TypeQ -- ^ Column type+ -> [Int] -- ^ Primary key index+ -> Q [Dec] -- ^ Declarations of primary constraint key+defineHasPrimaryKeyInstanceWithConfig config scm =+ defineHasPrimaryKeyInstance . fst . recordTemplate (recordConfig $ nameConfig config) scm++-- | Rule template to infer not-null key.+defineHasNotNullKeyInstance :: TypeQ -- ^ Record type+ -> Int -- ^ Column index+ -> Q [Dec] -- ^ Result 'ColumnConstraint' declaration+defineHasNotNullKeyInstance =+ defineHasColumnConstraintInstance [t| NotNull |]++-- | Rule template to infer not-null key.+defineHasNotNullKeyInstanceWithConfig :: Config -- ^ configuration parameters+ -> String -- ^ Schema name+ -> String -- ^ Table name+ -> Int -- ^ NotNull key index+ -> Q [Dec] -- ^ Declaration of not-null constraint key+defineHasNotNullKeyInstanceWithConfig config scm =+ defineHasNotNullKeyInstance . fst . recordTemplate (recordConfig $ nameConfig config) scm+++-- | Column projection path 'Pi' template.+columnTemplate' :: TypeQ -- ^ Record type+ -> VarName -- ^ Column declaration variable name+ -> ExpQ -- ^ Column index expression in record (begin with 0)+ -> TypeQ -- ^ Column type+ -> Q [Dec] -- ^ Column projection path declaration+columnTemplate' recType var' iExp colType = do+ let var = varName var'+ simpleValD var [t| Pi $recType $colType |]+ [| UnsafePi.definePi $(iExp) |]++-- | Column projection path 'Pi' and constraint key template.+columnTemplate :: Maybe (TypeQ, VarName) -- ^ May Constraint type and constraint object name+ -> TypeQ -- ^ Record type+ -> VarName -- ^ Column declaration variable name+ -> ExpQ -- ^ Column index expression in record (begin with 0)+ -> TypeQ -- ^ Column type+ -> Q [Dec] -- ^ Column projection path declaration+columnTemplate mayConstraint recType var' iExp colType = do+ col <- columnTemplate' recType var' iExp colType+ cr <- maybe+ (return [])+ ( \(constraint, cname') -> do+ simpleValD (varName cname') [t| Key $constraint $recType $colType |]+ [| unsafeDefineConstraintKey $(iExp) |] )+ mayConstraint+ return $ col ++ cr++-- | Column projection path 'Pi' templates.+defineColumns :: ConName -- ^ Record type name+ -> [((VarName, TypeQ), Maybe (TypeQ, VarName))] -- ^ Column info list+ -> Q [Dec] -- ^ Column projection path declarations+defineColumns recTypeName cols = do+ let defC ((cn, ct), mayCon) ix = columnTemplate mayCon (toTypeCon recTypeName) cn+ [| $(toVarExp . columnOffsetsVarNameDefault $ conName recTypeName) ! $(integralE ix) |] ct+ fmap concat . sequence $ zipWith defC cols [0 :: Int ..]++-- | Make column projection path and constraint key templates using default naming rule.+defineColumnsDefault :: ConName -- ^ Record type name+ -> [((String, TypeQ), Maybe TypeQ)] -- ^ Column info list+ -> Q [Dec] -- ^ Column projection path declarations+defineColumnsDefault recTypeName cols =+ defineColumns recTypeName [((varN n, ct), fmap (withCName n) mayC) | ((n, ct), mayC) <- cols]+ where varN name = varCamelcaseName (name ++ "'")+ withCName name t = (t, varCamelcaseName ("constraint_key_" ++ name))++-- | Rule template to infer table derivations.+defineTableDerivableInstance :: TypeQ -> String -> [String] -> Q [Dec]+defineTableDerivableInstance recordType' table columns =+ [d| instance TableDerivable $recordType' where+ derivedTable = Table.table $(stringE table) $(listE $ map stringE columns)+ |]++-- | Template to define inferred entries from table type.+defineTableDerivations :: VarName -- ^ Table declaration variable name+ -> VarName -- ^ Relation declaration variable name+ -> VarName -- ^ Insert statement declaration variable name+ -> VarName -- ^ InsertQuery statement declaration variable name+ -> TypeQ -- ^ Record type+ -> Q [Dec] -- ^ Table and Relation declaration+defineTableDerivations tableVar' relVar' insVar' insQVar' recordType' = do+ let tableVar = varName tableVar'+ tableDs <- simpleValD tableVar [t| Table $recordType' |]+ [| derivedTable |]+ let relVar = varName relVar'+ relDs <- simpleValD relVar [t| Relation () $recordType' |]+ [| derivedRelation |]+ let insVar = varName insVar'+ insDs <- simpleValD insVar [t| Insert $recordType' |]+ [| derivedInsert id' |]+ let insQVar = varName insQVar'+ insQDs <- simpleValD insQVar [t| forall p . Relation p $recordType' -> InsertQuery p |]+ [| derivedInsertQuery id' |]+ return $ concat [tableDs, relDs, insDs, insQDs]++-- | 'Table' and 'Relation' templates.+defineTableTypes :: VarName -- ^ Table declaration variable name+ -> VarName -- ^ Relation declaration variable name+ -> VarName -- ^ Insert statement declaration variable name+ -> VarName -- ^ InsertQuery statement declaration variable name+ -> TypeQ -- ^ Record type+ -> String -- ^ Table name in SQL ex. FOO_SCHEMA.table0+ -> [String] -- ^ Column names+ -> Q [Dec] -- ^ Table and Relation declaration+defineTableTypes tableVar' relVar' insVar' insQVar' recordType' table columns = do+ iDs <- defineTableDerivableInstance recordType' table columns+ dDs <- defineTableDerivations tableVar' relVar' insVar' insQVar' recordType'+ return $ iDs ++ dDs++tableSQL :: Bool -> SchemaNameMode -> IdentifierQuotation -> String -> String -> String+tableSQL normalize snm iq schema table = case snm of+ SchemaQualified -> (qt normalizeS) ++ '.' : (qt normalizeT)+ SchemaNotQualified -> (qt normalizeT)+ where+ normalizeS+ | normalize = map toUpper schema+ | otherwise = schema+ normalizeT+ | normalize = map toLower table+ | otherwise = table+ qt = quote iq++quote :: IdentifierQuotation -> String -> String+quote NoQuotation s = s+quote (Quotation q) s = q : (escape s) ++ q : []+ where escape = (>>= (\c -> if c == q then [q, q] else [c]))++derivationVarNameDefault :: String -> VarName+derivationVarNameDefault = (`varNameWithPrefix` "derivationFrom")++-- | Make 'TableDerivation' variable expression template from table name using default naming rule.+derivationExpDefault :: String -- ^ Table name string+ -> ExpQ -- ^ Result var Exp+derivationExpDefault = toVarExp . derivationVarNameDefault++tableVarNameDefault :: String -> VarName+tableVarNameDefault = (`varNameWithPrefix` "tableOf")++-- | Make 'Table' variable expression template from table name using default naming rule.+tableVarExpDefault :: String -- ^ Table name string+ -> ExpQ -- ^ Result var Exp+tableVarExpDefault = toVarExp . tableVarNameDefault++-- | Make 'Relation' variable expression template from table name using specified naming rule.+relationVarExp :: Config -- ^ Configuration which has naming rules of templates+ -> String -- ^ Schema name string+ -> String -- ^ Table name string+ -> ExpQ -- ^ Result var Exp+relationVarExp config scm = toVarExp . relationVarName (nameConfig config) scm++-- | Make template for record 'ProductConstructor' instance using specified naming rule.+defineProductConstructorInstanceWithConfig :: Config -> String -> String -> [Q Type] -> Q [Dec]+defineProductConstructorInstanceWithConfig config schema table colTypes = do+ let (recType, recData) = recordTemplate (recordConfig $ nameConfig config) schema table+ [d| instance ProductConstructor $(foldr (appT . (arrowT `appT`)) recType colTypes) where+ productConstructor = $(recData)+ |]++-- | Make templates about table and column metadatas using specified naming rule.+defineTableTypesWithConfig :: Config -- ^ Configuration to generate query with+ -> String -- ^ Schema name+ -> String -- ^ Table name+ -> [((String, TypeQ), Maybe TypeQ)] -- ^ Column names and types and constraint type+ -> Q [Dec] -- ^ Result declarations+defineTableTypesWithConfig config schema table columns = do+ let nmconfig = nameConfig config+ recConfig = recordConfig nmconfig+ tableDs <- defineTableTypes+ (tableVarNameDefault table)+ (relationVarName nmconfig schema table)+ (table `varNameWithPrefix` "insert")+ (table `varNameWithPrefix` "insertQuery")+ (fst $ recordTemplate recConfig schema table)+ (tableSQL (normalizedTableName config) (schemaNameMode config) (identifierQuotation config) schema table)+ (map ((quote (identifierQuotation config)) . fst . fst) columns)+ colsDs <- defineColumnsDefault (recordTypeName recConfig schema table) columns+ return $ tableDs ++ colsDs++-- | Make templates about table, column and haskell record using specified naming rule.+defineTableTypesAndRecord :: Config -- ^ Configuration to generate query with+ -> String -- ^ Schema name+ -> String -- ^ Table name+ -> [(String, TypeQ)] -- ^ Column names and types+ -> [Name] -- ^ Record derivings+ -> Q [Dec] -- ^ Result declarations+defineTableTypesAndRecord config schema table columns derives = do+ let recConfig = recordConfig $ nameConfig config+ recD <- defineRecordTypeWithConfig recConfig schema table columns derives+ rconD <- defineProductConstructorInstanceWithConfig config schema table [t | (_, t) <- columns]+ ctD <- [d| instance ShowConstantTermsSQL $(fst $ recordTemplate recConfig schema table) |]+ tableDs <- defineTableTypesWithConfig config schema table [(c, Nothing) | c <- columns ]+ return $ recD ++ rconD ++ ctD ++ tableDs++-- | Template of derived primary 'Query'.+definePrimaryQuery :: VarName -- ^ Variable name of result declaration+ -> TypeQ -- ^ Parameter type of 'Query'+ -> TypeQ -- ^ Record type of 'Query'+ -> ExpQ -- ^ 'Relation' expression+ -> Q [Dec] -- ^ Result 'Query' declaration+definePrimaryQuery toDef' paramType recType relE = do+ let toDef = varName toDef'+ simpleValD toDef+ [t| Query $paramType $recType |]+ [| relationalQuery (primary $relE) |]++-- | Template of derived primary 'Update'.+definePrimaryUpdate :: VarName -- ^ Variable name of result declaration+ -> TypeQ -- ^ Parameter type of 'Update'+ -> TypeQ -- ^ Record type of 'Update'+ -> ExpQ -- ^ 'Table' expression+ -> Q [Dec] -- ^ Result 'Update' declaration+definePrimaryUpdate toDef' paramType recType tableE = do+ let toDef = varName toDef'+ simpleValD toDef+ [t| KeyUpdate $paramType $recType |]+ [| primaryUpdate $tableE |]+++-- | SQL templates derived from primary key.+defineSqlsWithPrimaryKey :: VarName -- ^ Variable name of select query definition from primary key+ -> VarName -- ^ Variable name of update statement definition from primary key+ -> TypeQ -- ^ Primary key type+ -> TypeQ -- ^ Record type+ -> ExpQ -- ^ Relation expression+ -> ExpQ -- ^ Table expression+ -> Q [Dec] -- ^ Result declarations+defineSqlsWithPrimaryKey sel upd paramType recType relE tableE = do+ selD <- definePrimaryQuery sel paramType recType relE+ updD <- definePrimaryUpdate upd paramType recType tableE+ return $ selD ++ updD++-- | SQL templates derived from primary key using default naming rule.+defineSqlsWithPrimaryKeyDefault :: String -- ^ Table name of Database+ -> TypeQ -- ^ Primary key type+ -> TypeQ -- ^ Record type+ -> ExpQ -- ^ Relation expression+ -> ExpQ -- ^ Table expression+ -> Q [Dec] -- ^ Result declarations+defineSqlsWithPrimaryKeyDefault table =+ defineSqlsWithPrimaryKey sel upd+ where+ sel = table `varNameWithPrefix` "select"+ upd = table `varNameWithPrefix` "update"++-- | All templates about primary key.+defineWithPrimaryKey :: Config+ -> String -- ^ Schema name+ -> String -- ^ Table name string+ -> TypeQ -- ^ Type of primary key+ -> [Int] -- ^ Indexes specifies primary key+ -> Q [Dec] -- ^ Result declarations+defineWithPrimaryKey config schema table keyType ixs = do+ instD <- defineHasPrimaryKeyInstanceWithConfig config schema table keyType ixs+ let recType = fst $ recordTemplate (recordConfig $ nameConfig config) schema table+ tableE = tableVarExpDefault table+ relE = relationVarExp config schema table+ sqlsD <- defineSqlsWithPrimaryKeyDefault table keyType recType relE tableE+ return $ instD ++ sqlsD++-- | All templates about not-null key.+defineWithNotNullKeyWithConfig :: Config -> String -> String -> Int -> Q [Dec]+defineWithNotNullKeyWithConfig = defineHasNotNullKeyInstanceWithConfig++-- | Generate all templtes about table using specified naming rule.+defineTable :: Config -- ^ Configuration to generate query with+ -> String -- ^ Schema name string of Database+ -> String -- ^ Table name string of Database+ -> [(String, TypeQ)] -- ^ Column names and types+ -> [Name] -- ^ derivings for Record type+ -> [Int] -- ^ Primary key index+ -> Maybe Int -- ^ Not null key index+ -> Q [Dec] -- ^ Result declarations+defineTable config schema table columns derives primaryIxs mayNotNullIdx = do+ tblD <- defineTableTypesAndRecord config schema table columns derives+ let pairT x y = appT (appT (tupleT 2) x) y+ keyType = foldl1' pairT . map (snd . (columns !!)) $ primaryIxs+ primD <- case primaryIxs of+ [] -> return []+ ixs -> defineWithPrimaryKey config schema table keyType ixs+ nnD <- maybeD (\i -> defineWithNotNullKeyWithConfig config schema table i) mayNotNullIdx+ return $ tblD ++ primD ++ nnD+++-- | Unsafely inlining SQL string 'Query' in compile type.+unsafeInlineQuery :: TypeQ -- ^ Query parameter type+ -> TypeQ -- ^ Query result type+ -> String -- ^ SQL string query to inline+ -> VarName -- ^ Variable name for inlined query+ -> Q [Dec] -- ^ Result declarations+unsafeInlineQuery p r sql qVar' =+ simpleValD (varName qVar')+ [t| Query $p $r |]+ [| unsafeTypedQuery $(stringE sql) |]++-- | Extract param type and result type from defined Relation+reifyRelation :: Name -- ^ Variable name which has Relation type+ -> Q (Type, Type) -- ^ Extracted param type and result type from Relation type+reifyRelation relVar = do+ relInfo <- reify relVar+ case unVarI relInfo of+ Just (_, (AppT (AppT (ConT prn) p) r), _)+ | prn == ''Relation -> return (p, r)+ _ ->+ fail $ "expandRelation: Variable must have Relation type: " ++ show relVar++-- | Inlining composed 'Query' in compile type.+inlineQuery :: Name -- ^ Top-level variable name which has 'Relation' type+ -> Relation p r -- ^ Object which has 'Relation' type+ -> Config -- ^ Configuration to generate SQL+ -> QuerySuffix -- ^ suffix SQL words+ -> String -- ^ Variable name to define as inlined query+ -> Q [Dec] -- ^ Result declarations+inlineQuery relVar rel config sufs qns = do+ (p, r) <- reifyRelation relVar+ unsafeInlineQuery (return p) (return r)+ (relationalQuerySQL config rel sufs)+ (varCamelcaseName qns)++-- | Generate all templates against defined record like type constructor+-- other than depending on sql-value type.+makeRelationalRecordDefault :: Name -- ^ Type constructor name+ -> Q [Dec] -- ^ Result declaration+makeRelationalRecordDefault recTypeName = do+ let recTypeConName = ConName recTypeName+ (((tyCon, vars), _dataCon), (mayNs, cts)) <- reifyRecordType recTypeName+ pw <- Record.definePersistableWidthInstance tyCon vars+ cols <- case mayNs of+ Nothing -> return []+ Just ns -> case vars of+ [] -> do {- monomorphic case -}+ off <- Record.defineColumnOffsets recTypeConName+ cs <- defineColumnsDefault recTypeConName+ [ ((nameBase n, ct), Nothing) | n <- ns | ct <- cts ]+ return $ off ++ cs+ _:_ -> {- polymorphic case -}+ defineRecordProjections tyCon vars+ [varName $ varCamelcaseName (nameBase n ++ "'") | n <- ns]+ cts++ pc <- defineProductConstructor recTypeName+ let scPred v = classP ''ShowConstantTermsSQL [varT v]+ ct <- instanceD (mapM scPred vars) (appT [t| ShowConstantTermsSQL |] tyCon) []+ return $ concat [pw, cols, pc, [ct]]
+ src/Database/Relational/Table.hs view
@@ -0,0 +1,81 @@+-- |+-- Module : Database.Relational.Table+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines table type which has table metadatas.+module Database.Relational.Table (+ -- * Phantom typed table type+ Table, unType, name, shortName, width, columns, index, table, toMaybe, recordWidth,+ toSubQuery,++ -- * Table existence inference+ TableDerivable (..)+ ) where++import Data.Array (listArray)++import Database.Record.Persistable+ (PersistableWidth, PersistableRecordWidth, unsafePersistableRecordWidth)++import Database.Relational.Internal.UntypedTable (Untyped (Untyped), name', width', columns', (!))+import Database.Relational.Internal.String (StringSQL, stringSQL, )+import Database.Relational.SqlSyntax (SubQuery)+import qualified Database.Relational.SqlSyntax as Syntax+++-- | Phantom typed table type+newtype Table r = Table Untyped++-- | Untype table.+unType :: Table t -> Untyped+unType (Table u) = u++-- | Name string of table in SQL+name :: Table r -> String+name = name' . unType++-- | Not qualified name string of table in SQL+shortName :: Table r -> String+shortName = tail . dropWhile (/= '.') . name++-- | Width of table+width :: Table r -> Int+width = width' . unType++-- | Column name strings in SQL+columns :: Table r -> [StringSQL]+columns = columns' . unType++-- | Column name string in SQL specified by index+index :: Table r+ -> Int -- ^ Column index+ -> StringSQL -- ^ Column name String in SQL+index = (!) . unType++-- | Cast phantom type into 'Maybe' type.+toMaybe :: Table r -> Table (Maybe r)+toMaybe (Table t) = Table t++-- | Unsafely generate phantom typed table type.+table :: String -> [String] -> Table r+table n f = Table $ Untyped n w fa where+ w = length f+ fa = listArray (0, w - 1) $ map stringSQL f++-- | 'SubQuery' from 'Table'.+toSubQuery :: Table r -- ^ Typed 'Table' metadata+ -> SubQuery -- ^ Result 'SubQuery'+toSubQuery = Syntax.Table . unType++-- | Inference rule of 'Table' existence.+class PersistableWidth r => TableDerivable r where+ derivedTable :: Table r++-- | PersistableRecordWidth of table+recordWidth :: Table r -> PersistableRecordWidth r+recordWidth = unsafePersistableRecordWidth . width
+ src/Database/Relational/TupleInstances.hs view
@@ -0,0 +1,27 @@+{-# OPTIONS_GHC -fno-warn-orphans #-}++{-# LANGUAGE TemplateHaskell #-}+{-# LANGUAGE FlexibleInstances #-}+{-# LANGUAGE ScopedTypeVariables #-}++-- |+-- Module : Database.Relational.TupleInstances+-- Copyright : 2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines ProductConstructor instances and projection path objects of tuple types.+module Database.Relational.TupleInstances where++import Control.Applicative ((<$>))++import Database.Relational.BaseTH+ (defineTuplePi, defineTupleShowConstantInstance,)+++$(concat <$> mapM defineTuplePi [2..7])+$(concat <$> mapM defineTupleShowConstantInstance [2..7])+-- Generic instances of tuple types are generated from 2 to 7 in GHC.Generics.
+ src/Database/Relational/Type.hs view
@@ -0,0 +1,334 @@+-- |+-- Module : Database.Relational.Type+-- Copyright : 2013-2017 Kei Hibino+-- License : BSD3+--+-- Maintainer : ex8k.hibino@gmail.com+-- Stability : experimental+-- Portability : unknown+--+-- This module defines typed SQL.+module Database.Relational.Type (+ -- * Typed query statement+ Query (..), unsafeTypedQuery,++ relationalQuery', relationalQuery,++ relationalQuerySQL,++ -- * Typed update statement+ KeyUpdate (..), unsafeTypedKeyUpdate, typedKeyUpdate, typedKeyUpdateTable, derivedKeyUpdate,+ Update (..), unsafeTypedUpdate, typedUpdate', typedUpdate, derivedUpdate', derivedUpdate,+ typedUpdateAllColumn, derivedUpdateAllColumn', derivedUpdateAllColumn,++ updateSQL,++ -- * Typed insert statement+ Insert (..), untypeChunkInsert, chunkSizeOfInsert,+ unsafeTypedInsert', unsafeTypedInsert, typedInsert', typedInsert, derivedInsert,+ typedInsertValue', typedInsertValue, derivedInsertValue', derivedInsertValue,+ InsertQuery (..), unsafeTypedInsertQuery, typedInsertQuery', typedInsertQuery, derivedInsertQuery,++ insertQuerySQL,++ -- * Typed delete statement+ Delete (..), unsafeTypedDelete, typedDelete', typedDelete, derivedDelete', derivedDelete,++ deleteSQL,++ -- * Generalized interfaces+ UntypeableNoFetch (..)+ ) where++import Data.Monoid ((<>))++import Database.Record (PersistableWidth)++import Database.Relational.Internal.Config (Config, defaultConfig)+import Database.Relational.Internal.String (showStringSQL)++import Database.Relational.Monad.BaseType (Relation, sqlFromRelationWith)+import Database.Relational.Monad.Restrict (RestrictedStatement)+import Database.Relational.Monad.Assign (AssignStatement)+import Database.Relational.Monad.Register (Register)+import Database.Relational.Relation (tableOf)+import Database.Relational.Effect+ (Restriction, restriction', UpdateTarget, updateTarget', liftTargetAllColumn', InsertTarget, insertTarget',+ sqlWhereFromRestriction, sqlFromUpdateTarget, piRegister, sqlChunkFromInsertTarget, sqlFromInsertTarget)+import Database.Relational.Pi (Pi)+import Database.Relational.Table (Table, TableDerivable, derivedTable)+import Database.Relational.Projectable (PlaceHolders)+import Database.Relational.SimpleSql+ (QuerySuffix, showsQuerySuffix, insertPrefixSQL,+ updateOtherThanKeySQL, updatePrefixSQL, deletePrefixSQL)+++-- | Query type with place-holder parameter 'p' and query result type 'a'.+newtype Query p a = Query { untypeQuery :: String }++-- | Unsafely make typed 'Query' from SQL string.+unsafeTypedQuery :: String -- ^ Query SQL to type+ -> Query p a -- ^ Typed result+unsafeTypedQuery = Query++-- | Show query SQL string+instance Show (Query p a) where+ show = untypeQuery++-- | From 'Relation' into untyped SQL query string.+relationalQuerySQL :: Config -> Relation p r -> QuerySuffix -> String+relationalQuerySQL config rel qsuf = showStringSQL $ sqlFromRelationWith rel config <> showsQuerySuffix qsuf++-- | From 'Relation' into typed 'Query' with suffix SQL words.+relationalQuery' :: Relation p r -> QuerySuffix -> Query p r+relationalQuery' rel qsuf = unsafeTypedQuery $ relationalQuerySQL defaultConfig rel qsuf++-- | From 'Relation' into typed 'Query'.+relationalQuery :: Relation p r -> Query p r+relationalQuery = (`relationalQuery'` [])+++-- | Update type with key type 'p' and update record type 'a'.+-- Columns to update are record columns other than key columns,+-- So place-holder parameter type is the same as record type 'a'.+data KeyUpdate p a = KeyUpdate { updateKey :: Pi a p+ , untypeKeyUpdate :: String+ }++-- | Unsafely make typed 'KeyUpdate' from SQL string.+unsafeTypedKeyUpdate :: Pi a p -> String -> KeyUpdate p a+unsafeTypedKeyUpdate = KeyUpdate++-- | Make typed 'KeyUpdate' from 'Table' and key columns selector 'Pi'.+typedKeyUpdate :: Table a -> Pi a p -> KeyUpdate p a+typedKeyUpdate tbl key = unsafeTypedKeyUpdate key $ updateOtherThanKeySQL tbl key++-- | Make typed 'KeyUpdate' object using derived info specified by 'Relation' type.+typedKeyUpdateTable :: TableDerivable r => Relation () r -> Pi r p -> KeyUpdate p r+typedKeyUpdateTable = typedKeyUpdate . tableOf++-- derivedKeyUpdate'+-- Config parameter is not yet required for KeyUpdate.++-- | Make typed 'KeyUpdate' from derived table and key columns selector 'Pi'.+derivedKeyUpdate :: TableDerivable r => Pi r p -> KeyUpdate p r+derivedKeyUpdate = typedKeyUpdate derivedTable++-- | Show update SQL string+instance Show (KeyUpdate p a) where+ show = untypeKeyUpdate+++-- | Update type with place-holder parameter 'p'.+newtype Update p = Update { untypeUpdate :: String }++-- | Unsafely make typed 'Update' from SQL string.+unsafeTypedUpdate :: String -> Update p+unsafeTypedUpdate = Update++-- | Make untyped update SQL string from 'Table' and 'UpdateTarget'.+updateSQL :: Config -> Table r -> UpdateTarget p r -> String+updateSQL config tbl ut = showStringSQL $ updatePrefixSQL tbl <> sqlFromUpdateTarget config tbl ut++-- | Make typed 'Update' from 'Config', 'Table' and 'UpdateTarget'.+typedUpdate' :: Config -> Table r -> UpdateTarget p r -> Update p+typedUpdate' config tbl ut = unsafeTypedUpdate $ updateSQL config tbl ut++-- | Make typed 'Update' using 'defaultConfig', 'Table' and 'UpdateTarget'.+typedUpdate :: Table r -> UpdateTarget p r -> Update p+typedUpdate = typedUpdate' defaultConfig++targetTable :: TableDerivable r => UpdateTarget p r -> Table r+targetTable = const derivedTable++-- | Make typed 'Update' from 'Config', derived table and 'AssignStatement'+derivedUpdate' :: TableDerivable r => Config -> AssignStatement r (PlaceHolders p) -> Update p+derivedUpdate' config utc = typedUpdate' config (targetTable ut) ut where+ ut = updateTarget' utc++-- | Make typed 'Update' from 'defaultConfig', derived table and 'AssignStatement'+derivedUpdate :: TableDerivable r => AssignStatement r (PlaceHolders p) -> Update p+derivedUpdate = derivedUpdate' defaultConfig+++-- | Make typed 'Update' from 'Config', 'Table' and 'Restriction'.+-- Update target is all column.+typedUpdateAllColumn' :: PersistableWidth r+ => Config+ -> Table r+ -> Restriction p r+ -> Update (r, p)+typedUpdateAllColumn' config tbl r = typedUpdate' config tbl $ liftTargetAllColumn' r++-- | Make typed 'Update' from 'Table' and 'Restriction'.+-- Update target is all column.+typedUpdateAllColumn :: PersistableWidth r+ => Table r+ -> Restriction p r+ -> Update (r, p)+typedUpdateAllColumn tbl r = typedUpdate tbl $ liftTargetAllColumn' r++-- | Make typed 'Update' from 'Config', derived table and 'AssignStatement'.+-- Update target is all column.+derivedUpdateAllColumn' :: (PersistableWidth r, TableDerivable r)+ => Config+ -> RestrictedStatement r (PlaceHolders p)+ -> Update (r, p)+derivedUpdateAllColumn' config = typedUpdateAllColumn' config derivedTable .restriction'++-- | Make typed 'Update' from 'defaultConfig', derived table and 'AssignStatement'.+-- Update target is all column.+derivedUpdateAllColumn :: (PersistableWidth r, TableDerivable r)+ => RestrictedStatement r (PlaceHolders p)+ -> Update (r, p)+derivedUpdateAllColumn = derivedUpdateAllColumn' defaultConfig++-- | Show update SQL string+instance Show (Update p) where+ show = untypeUpdate+++-- | Insert type to insert record type 'a'.+data Insert a =+ Insert+ { untypeInsert :: String+ , chunkedInsert :: Maybe (String, Int)+ }++-- | Statement to use chunked insert+untypeChunkInsert :: Insert a -> String+untypeChunkInsert ins = maybe (untypeInsert ins) fst $ chunkedInsert ins++-- | Size to use chunked insert+chunkSizeOfInsert :: Insert a -> Int+chunkSizeOfInsert = maybe 1 snd . chunkedInsert++-- | Unsafely make typed 'Insert' from single insert and chunked insert SQL.+unsafeTypedInsert' :: String -> String -> Int -> Insert a+unsafeTypedInsert' s = curry (Insert s . Just)++-- | Unsafely make typed 'Insert' from single insert SQL.+unsafeTypedInsert :: String -> Insert a+unsafeTypedInsert s = Insert s Nothing++-- | Make typed 'Insert' from 'Table' and columns selector 'Pi' with configuration parameter.+typedInsert' :: PersistableWidth r => Config -> Table r -> Pi r r' -> Insert r'+typedInsert' config tbl =+ typedInsertValue' config tbl . insertTarget' . piRegister++-- | Make typed 'Insert' from 'Table' and columns selector 'Pi'.+typedInsert :: PersistableWidth r => Table r -> Pi r r' -> Insert r'+typedInsert = typedInsert' defaultConfig++-- | Table type inferred 'Insert'.+derivedInsert :: (PersistableWidth r, TableDerivable r) => Pi r r' -> Insert r'+derivedInsert = typedInsert derivedTable++-- | Make typed 'Insert' from 'Config', 'Table' and monadic builded 'InsertTarget' object.+typedInsertValue' :: Config -> Table r -> InsertTarget p r -> Insert p+typedInsertValue' config tbl it =+ unsafeTypedInsert'+ (showStringSQL $ sqlFromInsertTarget config tbl it)+ (showStringSQL ci) n+ where+ (ci, n) = sqlChunkFromInsertTarget config tbl it++-- | Make typed 'Insert' from 'Table' and monadic builded 'InsertTarget' object.+typedInsertValue :: Table r -> InsertTarget p r -> Insert p+typedInsertValue = typedInsertValue' defaultConfig++-- | Make typed 'Insert' from 'Config', derived table and monadic builded 'Register' object.+derivedInsertValue' :: TableDerivable r => Config -> Register r (PlaceHolders p) -> Insert p+derivedInsertValue' config rs = typedInsertValue' config (rt rs) $ insertTarget' rs+ where+ rt :: TableDerivable r => Register r (PlaceHolders p) -> Table r+ rt = const derivedTable++-- | Make typed 'Insert' from 'defaultConfig', derived table and monadic builded 'Register' object.+derivedInsertValue :: TableDerivable r => Register r (PlaceHolders p) -> Insert p+derivedInsertValue = derivedInsertValue' defaultConfig++-- | Show insert SQL string.+instance Show (Insert a) where+ show = untypeInsert++-- | InsertQuery type.+newtype InsertQuery p = InsertQuery { untypeInsertQuery :: String }++-- | Unsafely make typed 'InsertQuery' from SQL string.+unsafeTypedInsertQuery :: String -> InsertQuery p+unsafeTypedInsertQuery = InsertQuery++-- | Make untyped insert select SQL string from 'Table', 'Pi' and 'Relation'.+insertQuerySQL :: Config -> Table r -> Pi r r' -> Relation p r' -> String+insertQuerySQL config tbl pi' rel = showStringSQL $ insertPrefixSQL pi' tbl <> sqlFromRelationWith rel config++-- | Make typed 'InsertQuery' from columns selector 'Table', 'Pi' and 'Relation' with configuration parameter.+typedInsertQuery' :: Config -> Table r -> Pi r r' -> Relation p r' -> InsertQuery p+typedInsertQuery' config tbl pi' rel = unsafeTypedInsertQuery $ insertQuerySQL config tbl pi' rel++-- | Make typed 'InsertQuery' from columns selector 'Table', 'Pi' and 'Relation'.+typedInsertQuery :: Table r -> Pi r r' -> Relation p r' -> InsertQuery p+typedInsertQuery = typedInsertQuery' defaultConfig++-- | Table type inferred 'InsertQuery'.+derivedInsertQuery :: TableDerivable r => Pi r r' -> Relation p r' -> InsertQuery p+derivedInsertQuery = typedInsertQuery derivedTable++-- | Show insert SQL string.+instance Show (InsertQuery p) where+ show = untypeInsertQuery+++-- | Delete type with place-holder parameter 'p'.+newtype Delete p = Delete { untypeDelete :: String }++-- | Unsafely make typed 'Delete' from SQL string.+unsafeTypedDelete :: String -> Delete p+unsafeTypedDelete = Delete++-- | Make untyped delete SQL string from 'Table' and 'Restriction'.+deleteSQL :: Config -> Table r -> Restriction p r -> String+deleteSQL config tbl r = showStringSQL $ deletePrefixSQL tbl <> sqlWhereFromRestriction config tbl r++-- | Make typed 'Delete' from 'Config', 'Table' and 'Restriction'.+typedDelete' :: Config -> Table r -> Restriction p r -> Delete p+typedDelete' config tbl r = unsafeTypedDelete $ deleteSQL config tbl r++-- | Make typed 'Delete' from 'Table' and 'Restriction'.+typedDelete :: Table r -> Restriction p r -> Delete p+typedDelete = typedDelete' defaultConfig++restrictedTable :: TableDerivable r => Restriction p r -> Table r+restrictedTable = const derivedTable++-- | Make typed 'Delete' from 'Config', derived table and 'RestrictContext'+derivedDelete' :: TableDerivable r => Config -> RestrictedStatement r (PlaceHolders p) -> Delete p+derivedDelete' config rc = typedDelete' config (restrictedTable rs) rs where+ rs = restriction' rc++-- | Make typed 'Delete' from 'defaultConfig', derived table and 'RestrictContext'+derivedDelete :: TableDerivable r => RestrictedStatement r (PlaceHolders p) -> Delete p+derivedDelete = derivedDelete' defaultConfig++-- | Show delete SQL string+instance Show (Delete p) where+ show = untypeDelete+++-- | Untype interface for typed no-result type statments+-- with single type parameter which represents place-holder parameter 'p'.+class UntypeableNoFetch s where+ untypeNoFetch :: s p -> String++instance UntypeableNoFetch Insert where+ untypeNoFetch = untypeInsert++instance UntypeableNoFetch InsertQuery where+ untypeNoFetch = untypeInsertQuery++instance UntypeableNoFetch Update where+ untypeNoFetch = untypeUpdate++instance UntypeableNoFetch Delete where+ untypeNoFetch = untypeDelete
test/Model.hs view
@@ -9,8 +9,8 @@ import GHC.Generics (Generic) import Data.Int (Int32, Int64) -import Database.Relational.Query (defaultConfig)-import Database.Relational.Query.TH (defineTable, makeRelationalRecordDefault, defineScalarDegree)+import Database.Relational (defaultConfig)+import Database.Relational.TH (defineTable, makeRelationalRecordDefault, defineScalarDegree) $(defineTable defaultConfig "TEST" "set_a"
test/sqlsEq.hs view
@@ -2,15 +2,16 @@ import Test.QuickCheck.Simple (Test, defaultMain) import qualified Test.QuickCheck.Simple as QSimple -import Control.Applicative ((<$>), (<*>))- import Lex (eqProp, eqProp') import Model +import Control.Applicative ((<$>), (<*>))+import Data.Functor.ProductIsomorphic ((|$|), (|*|)) import Data.Int (Int32, Int64)-import Database.Relational.Query +import Database.Relational + tables :: [Test] tables = [ eqProp "setA" setA "SELECT int_a0, str_a1, str_a2 FROM TEST.set_a"@@ -282,9 +283,9 @@ _p_nested = mapM_ print [show nestedPiRec, show nestedPiCol, show nestedPi] --- Projection Operators+-- Record Operators -bin53 :: (Projection Flat Int32 -> Projection Flat Int32 -> Projection Flat r) -> Relation () r+bin53 :: (Record Flat Int32 -> Record Flat Int32 -> Record Flat r) -> Relation () r bin53 op = relation $ do return $ value 5 `op` value 3 @@ -292,7 +293,7 @@ strIn = relation $ return $ value "foo" `in'` values ["foo", "bar"] -boolTF :: (Projection Flat (Maybe Bool) -> Projection Flat (Maybe Bool) -> Projection Flat r) -> Relation () r+boolTF :: (Record Flat (Maybe Bool) -> Record Flat (Maybe Bool) -> Record Flat r) -> Relation () r boolTF op = relation $ do return $ valueTrue `op` valueFalse @@ -304,7 +305,7 @@ strLike = relation $ do return $ value "Hoge" `like` "H%" -_p_bin53 :: (Projection Flat Int32 -> Projection Flat Int32 -> Projection Flat r) -> IO ()+_p_bin53 :: (Record Flat Int32 -> Record Flat Int32 -> Record Flat r) -> IO () _p_bin53 = print . bin53 bin :: [Test]
test/sqlsEqArrow.hs view
@@ -6,10 +6,12 @@ import Lex (eqProp, eqProp') import Model -import Data.Int (Int32, Int64) import Control.Arrow (returnA, arr, (<<<), (***))-import Database.Relational.Query.Arrow+import Data.Int (Int32, Int64)+import Data.Functor.ProductIsomorphic ((|$|), (|*|)) +import Database.Relational.Arrow+ tables :: [Test] tables = [ eqProp "setA" setA "SELECT int_a0, str_a1, str_a2 FROM TEST.set_a"@@ -278,9 +280,9 @@ _p_nested = mapM_ print [show nestedPiRec, show nestedPiCol, show nestedPi] --- Projection Operators+-- Record Operators -bin53 :: (Projection Flat Int32 -> Projection Flat Int32 -> Projection Flat r) -> Relation () r+bin53 :: (Record Flat Int32 -> Record Flat Int32 -> Record Flat r) -> Relation () r bin53 op = relation $ proc () -> do returnA -< value 5 `op` value 3 @@ -288,7 +290,7 @@ strIn = relation $ proc () -> do returnA -< value "foo" `in'` values ["foo", "bar"] -boolTF :: (Projection Flat (Maybe Bool) -> Projection Flat (Maybe Bool) -> Projection Flat r) -> Relation () r+boolTF :: (Record Flat (Maybe Bool) -> Record Flat (Maybe Bool) -> Record Flat r) -> Relation () r boolTF op = relation $ proc () -> do returnA -< valueTrue `op` valueFalse @@ -300,7 +302,7 @@ strLike = relation $ proc () -> do returnA -< value "Hoge" `like` "H%" -_p_bin53 :: (Projection Flat Int32 -> Projection Flat Int32 -> Projection Flat r) -> IO ()+_p_bin53 :: (Record Flat Int32 -> Record Flat Int32 -> Record Flat r) -> IO () _p_bin53 = print . bin53 bin :: [Test]