on dev help sign in
some haddocks
commitb64339655adcb66e2134349e85282d4d44d8f627 authorEitan Chatav <eitan@Eitans-MacBook-Pro.local> dateThu 28 Feb 2019, 11:10 (8 years ago) parent3b9e0f4
4 files changed+139−46
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+75−32 squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+4−4 squeal-postgresql/src/Squeal/PostgreSQL/Render.hs+7−5 squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+53−5
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+75−32
@@ -1,5 +1,5 @@
11{-|
2−Module: Squeal.PostgreSQL.Query
2+Module: Squeal.PostgreSQL.Expression
33Description: Squeal expressions
44Copyright: (c) Eitan Chatav, 2017
55Maintainer: eitan@morphism.tech
@@ -210,7 +210,7 @@ import qualified Data.Aeson as JSON
210210import Data.Ratio
211211import Data.String
212212import Data.Word
213−import Generics.SOP hiding (from)
213+import Generics.SOP hiding (All, from)
214214import GHC.Generics ((:*:) (..))
215215import GHC.OverloadedLabels
216216import GHC.TypeLits
@@ -218,6 +218,7 @@ import Prelude hiding (id, (.))
218218
219219import qualified Data.ByteString as ByteString
220220import qualified GHC.Generics as GHC
221+import qualified Generics.SOP as SOP
221222
222223import Squeal.PostgreSQL.Render
223224import Squeal.PostgreSQL.Schema
@@ -1216,11 +1217,11 @@ jsonbBuildArray
12161217jsonbBuildArray = unsafeVariadicFunction "jsonb_build_array"
12171218
12181219unsafeRowFunction
1219− :: All Top elems
1220+ :: SOP.All SOP.Top elems
12201221 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12211222 -> [ByteString]
12221223unsafeRowFunction =
1223− (`appEndo` []) . hcfoldMap (Proxy :: Proxy Top)
1224+ (`appEndo` []) . hcfoldMap (Proxy :: SOP.Proxy SOP.Top)
12241225 (\(col `As` name) -> Endo $ \xs ->
12251226 renderAliasString name : renderSQL col : xs)
12261227 where
@@ -1231,7 +1232,7 @@ unsafeRowFunction =
12311232-- argument list. The elements of the argument list must alternate between text
12321233-- and values.
12331234jsonBuildObject
1234− :: All Top elems
1235+ :: SOP.All SOP.Top elems
12351236 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12361237 -> Expression outer grp commons schemas params from (nullity 'PGjson)
12371238jsonBuildObject
@@ -1244,7 +1245,7 @@ jsonBuildObject
12441245-- variadic argument list. The elements of the argument list must alternate
12451246-- between text and values.
12461247jsonbBuildObject
1247− :: All Top elems
1248+ :: SOP.All SOP.Top elems
12481249 => NP (Aliased (Expression outer grp commons schemas params from)) elems
12491250 -> Expression outer grp commons schemas params from (nullity 'PGjsonb)
12501251jsonbBuildObject
@@ -1427,6 +1428,11 @@ jsonbPretty = unsafeFunction "jsonb_pretty"
14271428aggregation
14281429-----------------------------------------}
14291430
1431+{- |
1432+`Aggregate` functions compute a single result from a set of input values.
1433+`Aggregate` functions can be used as `GroupedBy` `Expression`s as well
1434+as `WindowFunction`s.
1435+-}
14301436class Aggregate expr1 expr2 aggr
14311437 | aggr -> expr1, aggr -> expr2 where
14321438
@@ -1714,6 +1720,12 @@ class Aggregate expr1 expr2 aggr
17141720 :: expr1 (nullity ty)
17151721 -> aggr (nullity (PGAvg ty))
17161722
1723+{- |
1724+`Distinction`s are used for the input of `Aggregate` `Expression`s.
1725+`All` invokes the aggregate once for each input row.
1726+`Distinct` invokes the aggregate once for each distinct value of the expression
1727+(or distinct set of values, for multiple expressions) found in the input
1728+-}
17171729data Distinction expr ty
17181730 = All (expr ty)
17191731 | Distinct (expr ty)
@@ -1839,7 +1851,8 @@ type family PGAvg ty where
18391851type expressions
18401852-----------------------------------------}
18411853
1842−-- | `TypeExpression`s are used in `cast`s and `createTable` commands.
1854+-- | `TypeExpression`s are used in `cast`s and
1855+-- `Squeal.PostgreSQL.Definition.createTable` commands.
18431856newtype TypeExpression (schemas :: SchemasType) (ty :: NullityType)
18441857 = UnsafeTypeExpression { renderTypeExpression :: ByteString }
18451858 deriving (GHC.Generic,Show,Eq,Ord,NFData)
@@ -1955,21 +1968,21 @@ vararray ty = UnsafeTypeExpression $ renderSQL ty <> "[]"
19551968-- >>> renderSQL (fixarray @'[2] json)
19561969-- "json[2]"
19571970fixarray
1958− :: forall dims schemas nullity pg. All KnownNat dims
1971+ :: forall dims schemas nullity pg. SOP.All KnownNat dims
19591972 => TypeExpression schemas pg
19601973 -> TypeExpression schemas (nullity ('PGfixarray dims pg))
19611974fixarray ty = UnsafeTypeExpression $
19621975 renderSQL ty <> renderDims @dims
19631976 where
1964− renderDims :: forall ns. All KnownNat ns => ByteString
1977+ renderDims :: forall ns. SOP.All KnownNat ns => ByteString
19651978 renderDims =
19661979 ("[" <>)
19671980 . (<> "]")
19681981 . ByteString.intercalate "]["
19691982 . hcollapse
1970− $ hcmap (Proxy @KnownNat)
1983+ $ hcmap (SOP.Proxy @KnownNat)
19711984 (K . fromString . show . natVal)
1972− (hpure Proxy :: NP Proxy ns)
1985+ (hpure SOP.Proxy :: NP SOP.Proxy ns)
19731986
19741987-- | `pgtype` is a demoted version of a `PGType`
19751988class PGTyped schemas (ty :: NullityType) where
@@ -1999,7 +2012,7 @@ instance PGTyped schemas (nullity 'PGjsonb) where pgtype = jsonb
19992012instance PGTyped schemas ty
20002013 => PGTyped schemas (nullity ('PGvararray ty)) where
20012014 pgtype = vararray (pgtype @schemas @ty)
2002−instance (All KnownNat dims, PGTyped schemas ty)
2015+instance (SOP.All KnownNat dims, PGTyped schemas ty)
20032016 => PGTyped schemas (nullity ('PGfixarray dims ty)) where
20042017 pgtype = fixarray @dims (pgtype @schemas @ty)
20052018
@@ -2007,8 +2020,9 @@ instance (All KnownNat dims, PGTyped schemas ty)
20072020Sorting
20082021-----------------------------------------}
20092022
2010−-- | `SortExpression`s are used by `sortBy` to optionally sort the results
2011−-- of a `Query`. `Asc` or `Desc` set the sort direction of a `NotNull` result
2023+-- | `SortExpression`s are used by `orderBy` to optionally sort the results
2024+-- of a `Squeal.PostgreSQL.Query.Query`. `Asc` or `Desc`
2025+-- set the sort direction of a `NotNull` result
20122026-- column to ascending or descending. Ascending order puts smaller values
20132027-- first, where "smaller" is defined in terms of the `.<` operator. Similarly,
20142028-- descending order is determined with the `.>` operator. `AscNullsFirst`,
@@ -2016,26 +2030,37 @@ Sorting
20162030-- determine whether nulls appear before or after non-null values in the sort
20172031-- ordering of a `Null` result column.
20182032data SortExpression outer grp commons schemas params from where
2019− Asc
2020− :: Expression outer grp commons schemas params from ('NotNull ty)
2021− -> SortExpression outer grp commons schemas params from
2022− Desc
2023− :: Expression outer grp commons schemas params from ('NotNull ty)
2024− -> SortExpression outer grp commons schemas params from
2025− AscNullsFirst
2026− :: Expression outer grp commons schemas params from ('Null ty)
2027− -> SortExpression outer grp commons schemas params from
2028− AscNullsLast
2029− :: Expression outer grp commons schemas params from ('Null ty)
2030− -> SortExpression outer grp commons schemas params from
2031− DescNullsFirst
2032− :: Expression outer grp commons schemas params from ('Null ty)
2033− -> SortExpression outer grp commons schemas params from
2034− DescNullsLast
2035− :: Expression outer grp commons schemas params from ('Null ty)
2036− -> SortExpression outer grp commons schemas params from
2033+ Asc
2034+ :: Expression outer grp commons schemas params from ('NotNull ty)
2035+ -> SortExpression outer grp commons schemas params from
2036+ Desc
2037+ :: Expression outer grp commons schemas params from ('NotNull ty)
2038+ -> SortExpression outer grp commons schemas params from
2039+ AscNullsFirst
2040+ :: Expression outer grp commons schemas params from ('Null ty)
2041+ -> SortExpression outer grp commons schemas params from
2042+ AscNullsLast
2043+ :: Expression outer grp commons schemas params from ('Null ty)
2044+ -> SortExpression outer grp commons schemas params from
2045+ DescNullsFirst
2046+ :: Expression outer grp commons schemas params from ('Null ty)
2047+ -> SortExpression outer grp commons schemas params from
2048+ DescNullsLast
2049+ :: Expression outer grp commons schemas params from ('Null ty)
2050+ -> SortExpression outer grp commons schemas params from
20372051deriving instance Show (SortExpression outer grp commons schemas params from)
20382052
2053+{- |
2054+The `orderBy` clause causes the result rows of a `Squeal.PostgreSQL.Query.TableExpression`
2055+to be sorted according to the specified `SortExpression`(s).
2056+If two rows are equal according to the leftmost expression,
2057+they are compared according to the next expression and so on.
2058+If they are equal according to all specified expressions,
2059+they are returned in an implementation-dependent order.
2060+
2061+You can also control the order in which rows are processed by window functions
2062+using `orderBy` within `Squeal.PostgreSQL.Query.Over`.
2063+-}
20392064class OrderBy expr where
20402065 orderBy
20412066 :: [SortExpression outer grp commons schemas params from]
@@ -2054,6 +2079,8 @@ instance RenderSQL (SortExpression outer grp commons schemas params from) where
20542079 AscNullsLast expression -> renderSQL expression <+> "ASC NULLS LAST"
20552080 DescNullsLast expression -> renderSQL expression <+> "DESC NULLS LAST"
20562081
2082+-- | A `WindowDefinition` is a set of table rows that are somehow related
2083+-- to the current row
20572084data WindowDefinition outer grp commons schemas params from where
20582085 WindowDefinition
20592086 :: SListI bys
@@ -2077,12 +2104,28 @@ instance RenderSQL (WindowDefinition outer commons schemas from grp params) wher
20772104 srts -> " ORDER" <+> "BY"
20782105 <+> commaSeparated (renderSQL <$> srts)
20792106
2107+{- |
2108+The `partitionBy` clause within `Squeal.PostgreSQL.Query.Over` divides the rows into groups,
2109+or partitions, that share the same values of the `partitionBy` `Expression`(s).
2110+For each row, the window function is computed across the rows that fall into
2111+the same partition as the current row.
2112+-}
20802113partitionBy
20812114 :: SListI bys
20822115 => NP (Expression outer grp commons schemas params from) bys
20832116 -> WindowDefinition outer grp commons schemas params from
20842117partitionBy bys = WindowDefinition bys []
20852118
2119+{- |
2120+A window function performs a calculation across a set of table rows
2121+that are somehow related to the current row. This is comparable to the type
2122+of calculation that can be done with an aggregate function.
2123+However, window functions do not cause rows to become grouped into a single
2124+output row like non-window aggregate calls would.
2125+Instead, the rows retain their separate identities.
2126+Behind the scenes, the window function is able to access more than
2127+just the current row of the query result.
2128+-}
20862129newtype WindowFunction
20872130 (outer :: FromType)
20882131 (grp :: Grouping)
squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+4−4
@@ -612,11 +612,11 @@ data TableExpression
612612 -- will be returned (but possibly fewer, if the query itself yields
613613 -- fewer rows).
614614 , offsetClause :: [Word64]
615− -- ^ The `offsetClause` is combined with `+` to give an offset count
615+ -- ^ The `offsetClause` is combined with `Prelude.+` to give an offset count
616616 -- if nonempty. The offset count says to skip that many rows before
617617 -- beginning to return rows. The rows are skipped before the limit count
618618 -- is applied.
619− }
619+ } deriving (GHC.Generic)
620620
621621-- | Render a `TableExpression`
622622instance RenderSQL (TableExpression outer grp commons schemas params from) where
@@ -648,7 +648,7 @@ instance RenderSQL (TableExpression outer grp commons schemas params from) where
648648-- | A `from` generates a `TableExpression` from a table reference that can be
649649-- a table name, or a derived table such as a subquery, a JOIN construct,
650650-- or complex combinations of these. A `from` may be transformed by `where_`,
651−-- `group`, `having`, `orderBy`, `limit` and `offset`, using the `&` operator
651+-- `groupBy`, `having`, `orderBy`, `limit` and `offset`, using the `&` operator
652652-- to match the left-to-right sequencing of their placement in SQL.
653653from
654654 :: FromClause outer commons schemas params from -- ^ table reference
@@ -987,7 +987,7 @@ fullOuterJoin right on left = UnsafeFromClause $
987987Grouping
988988-----------------------------------------}
989989
990−-- | `By`s are used in `group` to reference a list of columns which are then
990+-- | `By`s are used in `groupBy` to reference a list of columns which are then
991991-- used to group together those rows in a table that have the same values
992992-- in all the columns listed. @By \#col@ will reference an unambiguous
993993-- column @col@; otherwise @By2 (\#tab \! \#col)@ will reference a table
squeal-postgresql/src/Squeal/PostgreSQL/Render.hs+7−5
@@ -41,9 +41,10 @@ import Data.Monoid ((<>))
4141import Data.Text (Text)
4242import Generics.SOP
4343import GHC.Exts
44−import GHC.TypeLits
45−import qualified Data.Text as T
46−import qualified Data.Text.Encoding as T
44+import GHC.TypeLits hiding (Text)
45+
46+import qualified Data.Text as Text
47+import qualified Data.Text.Encoding as Text
4748import qualified Data.ByteString as ByteString
4849import qualified Data.ByteString.Char8 as Char8
4950
@@ -66,11 +67,12 @@ doubleQuoted str = "\"" <> str <> "\""
6667
6768-- | Add single quotes around a `Text` and escape single quotes within it.
6869singleQuotedText :: Text -> ByteString
69−singleQuotedText str = "'" <> T.encodeUtf8 (T.replace "'" "''" str) <> "'"
70+singleQuotedText str =
71+ "'" <> Text.encodeUtf8 (Text.replace "'" "''" str) <> "'"
7072
7173-- | Add single quotes around a `ByteString` and escape single quotes within it.
7274singleQuotedUtf8 :: ByteString -> ByteString
73−singleQuotedUtf8 = singleQuotedText . T.decodeUtf8
75+singleQuotedUtf8 = singleQuotedText . Text.decodeUtf8
7476
7577-- | Comma separate the renderings of a heterogeneous list.
7678renderCommaSeparated
squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+53−5
@@ -273,7 +273,13 @@ data TableConstraint
273273 | PrimaryKey [Symbol]
274274 | ForeignKey [Symbol] Symbol [Symbol]
275275
276−-- | A `TableConstraints` is a row of `TableConstraint`s.
276+{- | A `TableConstraints` is a row of `TableConstraint`s.
277+
278+>>> :{
279+type family UsersConstraints :: TableConstraints where
280+ UsersConstraints = '[ "pk_users" ::: 'PrimaryKey '["id"] ]
281+:}
282+-}
277283type TableConstraints = [(Symbol,TableConstraint)]
278284
279285-- | A `ForeignKey` must reference columns that either are
@@ -442,8 +448,12 @@ instance {-# OVERLAPPING #-} KnownSymbol alias
442448instance {-# OVERLAPPABLE #-} (KnownSymbol alias, Has alias fields field)
443449 => Has alias (field' ': fields) field
444450
445−class HasIn fields (x :: (Symbol, a)) where
446−instance (Has alias fields field) => HasIn fields '(alias, field) where
451+{-| @HasIn fields (alias ::: field)@ is a constraint that proves that
452+@fields@ has a field of @alias ::: field@. It is used in @UPDATE@s to
453+choose which subfields to update.
454+-}
455+class HasIn fields field where
456+instance (Has alias fields field) => HasIn fields (alias ::: field) where
447457
448458-- | Utility class for `AllUnique` to provide nicer error messages.
449459class IsNotElem x isElem where
@@ -452,11 +462,16 @@ instance (TypeError ( 'Text "Cannot assign to "
452462 ':<>: 'ShowType alias
453463 ':<>: 'Text " more than once"))
454464 => IsNotElem '(alias, a) 'True where
455− -- | No elem of @xs@ appears more than once, in the context of assignment.
465+
466+-- | No elem of @xs@ appears more than once, in the context of assignment.
456467class AllUnique (xs :: [(Symbol, a)]) where
457468instance AllUnique '[] where
458469instance (IsNotElem x (Elem x xs), AllUnique xs) => AllUnique (x ': xs) where
459470
471+{- |
472+The `DefaultAliasable` class is intended to help with Scrap your Nils
473+for default inserts and updates.
474+-}
460475class KnownSymbol alias
461476 => DefaultAliasable alias aliased | aliased -> alias where
462477 defaultAs :: Alias alias -> aliased
@@ -483,6 +498,21 @@ class IsQualified table column expression where
483498 infixl 9 !
484499instance IsQualified table column (Alias table, Alias column) where (!) = (,)
485500
501+{-| `QualifiedAlias`es enables multi-schema support by allowing a reference
502+to a `Table`, `Typedef` or `View` to be qualified by their schemas. By default,
503+a qualifier of @public@ is provided.
504+
505+>>> :{
506+let
507+ alias1 :: QualifiedAlias "sch" "tab"
508+ alias1 = #sch ! #tab
509+ alias2 :: QualifiedAlias "public" "vw"
510+ alias2 = #vw
511+in printSQL alias1 >> printSQL alias2
512+:}
513+"sch"."tab"
514+"vw"
515+-}
486516data QualifiedAlias (qualifier :: Symbol) (alias :: Symbol) = QualifiedAlias
487517 deriving (Eq,GHC.Generic,Ord,Show,NFData)
488518instance (q ~ q', a ~ a') => IsQualified q a (QualifiedAlias q' a') where
@@ -621,7 +651,7 @@ type family Drop alias xs where
621651 Drop alias (x ': xs) = x ': Drop alias xs
622652
623653-- | @Alter alias x xs@ replaces the type associated with an @alias@ in @xs@
624−-- with the type `x` and is used in `Squeal.PostgreSQL.Definition.alterTable`
654+-- with the type @x@ and is used in `Squeal.PostgreSQL.Definition.alterTable`
625655-- and `Squeal.PostgreSQL.Definition.alterColumn`.
626656type family Alter alias x xs where
627657 Alter alias x1 (alias ::: x0 ': xs) = alias ::: x1 ': xs
@@ -691,8 +721,26 @@ type family Schema :: SchemaType where
691721-}
692722type SchemaType = [(Symbol,SchemumType)]
693723
724+{- |
725+A database contains one or more named schemas, which in turn contain tables.
726+The same object name can be used in different schemas without conflict;
727+for example, both schema1 and myschema can contain tables named mytable.
728+Unlike databases, schemas are not rigidly separated:
729+a user can access objects in any of the schemas in the database they are connected to,
730+if they have privileges to do so.
731+
732+There are several reasons why one might want to use schemas:
733+
734+ * To allow many users to use one database without interfering with each other.
735+ * To organize database objects into logical groups to make them more manageable.
736+ * Third-party applications can be put into separate schemas
737+ so they do not collide with the names of other objects.
738+-}
694739type SchemasType = [(Symbol,SchemaType)]
695740
741+{-|
742+
743+-}
696744type family Public (schema :: SchemaType) :: SchemasType
697745 where Public schema = '["public" ::: schema]
698746