on dev help sign in
almost...
commita28d35a8f634a0865b204a089b074675167e84a7 authorEitan Chatav <eitan.chatav@gmail.com> dateSun 24 Dec 2017, 15:20 (9 years ago) parent56462b3
4 files changed+80−105
squeal-postgresql/src/Squeal/PostgreSQL/Definition.hs+23−13 squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+35−70 squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+15−15 squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+7−7
squeal-postgresql/src/Squeal/PostgreSQL/Definition.hs+23−13
@@ -106,18 +106,16 @@ CREATE statements
106106-- :}
107107-- "CREATE TABLE tab (a int, b real);"
108108createTable
109− :: ( KnownSymbol tab
109+ :: ( KnownSymbol table
110110 , columns ~ (col ': cols)
111111 , SOP.SListI columns
112− , SOP.SListI constraints
113− , table ~ (constraints :=> columns))
114− => Alias tab -- ^ the name of the table to add
112+ , SOP.SListI constraints )
113+ => Alias table -- ^ the name of the table to add
115114 -> NP (Aliased TypeExpression) columns
116115 -- ^ the names and datatype of each column
117− -> NP (Aliased (TableConstraintExpression schema (UnconstrainColumns columns)))
118− constraints
116+ -> NP (Aliased (TableConstraintExpression schema columns)) constraints
119117 -- ^ constraints that must hold for the table
120− -> Definition schema (Create tab table schema)
118+ -> Definition schema (Create table (constraints :=> columns) schema)
121119createTable table columns constraints = UnsafeDefinition $
122120 "CREATE TABLE" <+> renderAlias table
123121 <+> parenthesized
@@ -151,12 +149,23 @@ createTable table columns constraints = UnsafeDefinition $
151149-- even if the value came from the default value definition.
152150newtype TableConstraintExpression
153151 (schema :: SchemaType)
154− (columns :: RelationType)
152+ (columns :: ColumnsType)
155153 (tableConstraint :: TableConstraint)
156154 = UnsafeTableConstraintExpression
157155 { renderTableConstraintExpression :: ByteString }
158156 deriving (GHC.Generic,Show,Eq,Ord,NFData)
159157
158+data Column
159+ (columns :: ColumnsType)
160+ (column :: (Symbol,ColumnType))
161+ where
162+ Column
163+ :: Has column columns ty
164+ => Column columns (column ::: ty)
165+deriving instance Show (Column columns columnty)
166+deriving instance Eq (Column columns columnty)
167+deriving instance Ord (Column columns columnty)
168+
160169-- | A `check` constraint is the most generic `TableConstraint` type.
161170-- It allows you to specify that the value in a certain column must satisfy
162171-- a Boolean (truth-value) expression.
@@ -170,7 +179,7 @@ newtype TableConstraintExpression
170179-- :}
171180-- "CREATE TABLE tab (a int NOT NULL, b int NOT NULL, CONSTRAINT inequality CHECK ((a > b)));"
172181check
173− :: Condition '[table ::: columns] 'Ungrouped '[]
182+ :: Condition '[table ::: UnconstrainColumns columns] 'Ungrouped '[]
174183 -- ^ condition to check
175184 -> TableConstraintExpression schema columns 'Check
176185check condition = UnsafeTableConstraintExpression $
@@ -257,14 +266,15 @@ primaryKey columns = UnsafeTableConstraintExpression $
257266-- :}
258267-- "CREATE TABLE users (id serial, username text NOT NULL, CONSTRAINT pk_id PRIMARY KEY (id)); CREATE TABLE emails (id serial, userid integer NOT NULL, email text NOT NULL, CONSTRAINT pk_id PRIMARY KEY (id), CONSTRAINT fk_user_id FOREIGN KEY (userid) REFERENCES users (id) ON DELETE CASCADE ON UPDATE RESTRICT);"
259268foreignKey
260− :: ( HasTable tab (UnconstrainSchema schema) refcolumns
269+ :: ( Has table schema reftable
270+ , reftable ~ (constraints :=> refsubcolumns)
261271 , SameTypes subcolumns refsubcolumns
262272 , AllNotNull subcolumns
263273 , SOP.SListI subcolumns
264274 , SOP.SListI refsubcolumns)
265275 => NP (Column columns) subcolumns
266276 -- ^ column or columns in the table
267− -> Alias tab
277+ -> Alias table
268278 -- ^ reference table
269279 -> NP (Column refcolumns) refsubcolumns
270280 -- ^ reference column or columns in the reference table
@@ -273,7 +283,7 @@ foreignKey
273283 -> OnUpdateClause
274284 -- ^ what to do when reference is updated
275285 -> TableConstraintExpression schema columns
276− ('ForeignKey (Aliases subcolumns) tab (Aliases refsubcolumns))
286+ ('ForeignKey (Aliases subcolumns) table (Aliases refsubcolumns))
277287foreignKey columns reftable refcolumns onDelete onUpdate =
278288 UnsafeTableConstraintExpression $
279289 "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
@@ -378,7 +388,7 @@ alterTableRename table0 table1 = UnsafeDefinition $
378388addConstraint
379389 :: KnownSymbol constraintName
380390 => Alias constraintName
381− -> TableConstraintExpression schema (UnconstrainColumns (UnconstrainTable table)) constraint
391+ -> TableConstraintExpression schema table constraint
382392 -> AlterTable schema table (AddConstraint constraintName constraint table)
383393addConstraint constraintName constraint = UnsafeAlterTable $
384394 "ADD" <+> "CONSTRAINT" <+> renderAlias constraintName
squeal-postgresql/src/Squeal/PostgreSQL/Expression.hs+35−70
@@ -37,9 +37,8 @@ module Squeal.PostgreSQL.Expression
3737 ( -- * Expression
3838 Expression (UnsafeExpression, renderExpression)
3939 , HasParameter (param)
40− , HasColumn (getColumn)
41− , Column (Column)
42− , renderColumn
40+ -- , Column (Column)
41+ -- , renderColumn
4342 , GroupedBy (getGroup1, getGroup2)
4443 -- ** Null
4544 , null_
@@ -100,8 +99,7 @@ module Squeal.PostgreSQL.Expression
10099 , every, everyDistinct
101100 , max_, maxDistinct, min_, minDistinct
102101 -- * Tables
103− , Table (UnsafeTable, renderTable)
104− , HasTable (getTable)
102+ , Subtable (UnsafeSubtable, renderSubtable)
105103 , TypeExpression (UnsafeTypeExpression, renderTypeExpression)
106104 , PGTyped (pgtype)
107105 , bool
@@ -206,32 +204,11 @@ instance {-# OVERLAPPING #-} PGTyped (PGTypeOf ty1)
206204instance {-# OVERLAPPABLE #-} (KnownNat n, HasParameter (n-1) params ty)
207205 => HasParameter n (ty' : params) ty
208206
209−{- | A `HasColumn` constraint indicates an unqualified column reference.
210−`getColumn` can only be unambiguous when the `TableExpression` the column
211−references is unique, in which case the column may be referenced using
212−@-XOverloadedLabels@. Otherwise, combined with a `HasTable` constraint, the
213−qualified column reference operator `!` may be used.
214−-}
215−class KnownSymbol column => HasColumn
216− (column :: Symbol)
217− (columns :: RelationType)
218− (ty :: NullityType)
219− | column columns -> ty where
220− getColumn
221− :: HasUnique table tables columns
222− => Alias column
223− -> Expression tables 'Ungrouped params ty
224− getColumn column = UnsafeExpression $ renderAlias column
225−instance {-# OVERLAPPING #-} KnownSymbol column
226− => HasColumn column (column ::: ty ': tys) ty
227−instance {-# OVERLAPPABLE #-} (KnownSymbol column, HasColumn column table ty)
228− => HasColumn column (ty' ': table) ty
229−
230−instance (HasColumn column columns ty, HasUnique table tables columns)
207+instance (HasUnique table tables columns, Has column columns ty)
231208 => IsLabel column (Expression tables 'Ungrouped params ty) where
232− fromLabel = getColumn (Alias @column)
209+ fromLabel = UnsafeExpression $ renderAlias (Alias @column)
233210
234−instance (HasTable table tables columns, HasColumn column columns ty)
211+instance (Has table tables columns, Has column columns ty)
235212 => IsTableColumn table column (Expression tables 'Ungrouped params ty) where
236213 table ! column = UnsafeExpression $
237214 renderAlias table <> "." <> renderAlias column
@@ -240,21 +217,21 @@ instance (HasTable table tables columns, HasColumn column columns ty)
240217-- in `Squeel.PostgreSQL.Definition.unique` and other
241218-- `Squeel.PostgreSQL.Definition.TableConstraint`s to witness a
242219-- subcolumns relationship.
243−data Column
244− (columns :: RelationType)
245− (columnty :: (Symbol,NullityType))
246− where
247− Column
248− :: HasColumn column columns ty
249− => Alias column
250− -> Column columns (column ::: ty)
251−deriving instance Show (Column columns columnty)
252−deriving instance Eq (Column columns columnty)
253−deriving instance Ord (Column columns columnty)
254−
255−-- | Render a `Column`.
256−renderColumn :: Column columns columnty -> ByteString
257−renderColumn (Column column) = renderAlias column
220+-- data Column
221+-- (columns :: RelationType)
222+-- (columnty :: (Symbol,NullityType))
223+-- where
224+-- Column
225+-- :: Has column columns ty
226+-- => Alias column
227+-- -> Column columns (column ::: ty)
228+-- deriving instance Show (Column columns columnty)
229+-- deriving instance Eq (Column columns columnty)
230+-- deriving instance Ord (Column columns columnty)
231+
232+-- -- | Render a `Column`.
233+-- renderColumn :: Column columns columnty -> ByteString
234+-- renderColumn (Column column) = renderAlias column
258235
259236{- | A `GroupedBy` constraint indicates that a table qualified column is
260237a member of the auxiliary namespace created by @GROUP BY@ clauses and thus,
@@ -263,12 +240,12 @@ may be called in an output `Expression` without aggregating.
263240class (KnownSymbol table, KnownSymbol column)
264241 => GroupedBy table column bys where
265242 getGroup1
266− :: (HasUnique table tables columns, HasColumn column columns ty)
243+ :: (HasUnique table tables columns, Has column columns ty)
267244 => Alias column
268245 -> Expression tables ('Grouped bys) params ty
269246 getGroup1 column = UnsafeExpression $ renderAlias column
270247 getGroup2
271− :: (HasTable table tables columns, HasColumn column columns ty)
248+ :: (Has table tables columns, Has column columns ty)
272249 => Alias table
273250 -> Alias column
274251 -> Expression tables ('Grouped bys) params ty
@@ -284,15 +261,15 @@ instance {-# OVERLAPPABLE #-}
284261
285262instance
286263 ( HasUnique table tables columns
287− , HasColumn column columns ty
264+ , Has column columns ty
288265 , GroupedBy table column bys
289266 ) => IsLabel column
290267 (Expression tables ('Grouped bys) params ty) where
291268 fromLabel = getGroup1 (Alias @column)
292269
293270instance
294− ( HasTable table tables columns
295− , HasColumn column columns ty
271+ ( Has table tables columns
272+ , Has column columns ty
296273 , GroupedBy table column bys
297274 ) => IsTableColumn table column
298275 (Expression tables ('Grouped bys) params ty) where (!) = getGroup2
@@ -961,31 +938,19 @@ minDistinct = unsafeAggregateDistinct "min"
961938tables
962939-----------------------------------------}
963940
964−-- | A `Table` from a schema without its alias with an `IsLabel` instance
941+-- | A `Subtable` from a table expression is a way
965942-- to call a table reference by its alias.
966−newtype Table
967− (schema :: RelationProduct)
943+newtype Subtable
944+ (table :: RelationProduct)
968945 (columns :: RelationType)
969− = UnsafeTable { renderTable :: ByteString }
946+ = UnsafeSubtable { renderSubtable :: ByteString }
970947 deriving (GHC.Generic,Show,Eq,Ord,NFData)
971−
972−-- | A `HasTable` constraint indicates a table reference.
973−class KnownSymbol table => HasTable
974− (table :: Symbol)
975− (tables :: RelationProduct)
948+instance Has
949+ (subtable :: Symbol)
950+ (table :: RelationProduct)
976951 (columns :: RelationType)
977− | table tables -> columns where
978− getTable :: Alias table -> Table tables columns
979− getTable table = UnsafeTable $ renderAlias table
980−instance {-# OVERLAPPING #-} KnownSymbol table
981− => HasTable table ((table ::: columns) ': tables) columns
982−instance {-# OVERLAPPABLE #-}
983− (KnownSymbol table, HasTable table schema columns)
984− => HasTable table (table' ': schema) columns
985−
986−instance HasTable table schema columns
987− => IsLabel table (Table schema columns) where
988− fromLabel = getTable (Alias @table)
952+ => IsLabel subtable (Subtable table columns) where
953+ fromLabel = UnsafeSubtable $ renderAlias (Alias @subtable)
989954
990955{-----------------------------------------
991956type expressions
squeal-postgresql/src/Squeal/PostgreSQL/Query.hs+15−15
@@ -45,7 +45,7 @@ module Squeal.PostgreSQL.Query
4545 , selectDistinctDotStar
4646 -- * Table Expressions
4747 , TableExpression (..)
48− , renderTableExpression
48+ , renderSubtableExpression
4949 , from
5050 , where_
5151 , group
@@ -348,7 +348,7 @@ select
348348select list tabs = UnsafeQuery $
349349 "SELECT"
350350 <+> renderCommaSeparated (renderAliasedAs renderExpression) list
351− <+> renderTableExpression tabs
351+ <+> renderSubtableExpression tabs
352352
353353-- | After the select list has been processed, the result table can
354354-- be subject to the elimination of duplicate rows using `selectDistinct`.
@@ -362,7 +362,7 @@ selectDistinct
362362selectDistinct list tabs = UnsafeQuery $
363363 "SELECT DISTINCT"
364364 <+> renderCommaSeparated (renderAliasedAs renderExpression) list
365− <+> renderTableExpression tabs
365+ <+> renderSubtableExpression tabs
366366
367367-- | The simplest kind of query is `selectStar` which emits all columns
368368-- that the table expression produces.
@@ -371,7 +371,7 @@ selectStar
371371 => TableExpression schema params tables 'Ungrouped
372372 -- ^ intermediate virtual table
373373 -> Query schema params columns
374−selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderTableExpression tabs
374+selectStar tabs = UnsafeQuery $ "SELECT" <+> "*" <+> renderSubtableExpression tabs
375375
376376-- | A `selectDistinctStar` emits all columns that the table expression
377377-- produces and eliminates duplicate rows.
@@ -381,24 +381,24 @@ selectDistinctStar
381381 -- ^ intermediate virtual table
382382 -> Query schema params columns
383383selectDistinctStar tabs = UnsafeQuery $
384− "SELECT DISTINCT" <+> "*" <+> renderTableExpression tabs
384+ "SELECT DISTINCT" <+> "*" <+> renderSubtableExpression tabs
385385
386386-- | When working with multiple tables, it can also be useful to ask
387387-- for all the columns of a particular table, using `selectDotStar`.
388388selectDotStar
389− :: HasTable table tables columns
389+ :: Has table tables columns
390390 => Alias table
391391 -- ^ particular virtual subtable
392392 -> TableExpression schema params tables 'Ungrouped
393393 -- ^ intermediate virtual table
394394 -> Query schema params columns
395395selectDotStar table tables = UnsafeQuery $
396− "SELECT" <+> renderAlias table <> ".*" <+> renderTableExpression tables
396+ "SELECT" <+> renderAlias table <> ".*" <+> renderSubtableExpression tables
397397
398398-- | A `selectDistinctDotStar` asks for all the columns of a particular table,
399399-- and eliminates duplicate rows.
400400selectDistinctDotStar
401− :: HasTable table tables columns
401+ :: Has table tables columns
402402 => Alias table
403403 -- ^ particular virtual subtable
404404 -> TableExpression schema params tables 'Ungrouped
@@ -406,7 +406,7 @@ selectDistinctDotStar
406406 -> Query schema params columns
407407selectDistinctDotStar table tables = UnsafeQuery $
408408 "SELECT DISTINCT" <+> renderAlias table <> ".*"
409− <+> renderTableExpression tables
409+ <+> renderSubtableExpression tables
410410
411411{-----------------------------------------
412412Table Expressions
@@ -466,10 +466,10 @@ data TableExpression
466466 }
467467
468468-- | Render a `TableExpression`
469−renderTableExpression
469+renderSubtableExpression
470470 :: TableExpression schema params tables grouping
471471 -> ByteString
472−renderTableExpression
472+renderSubtableExpression
473473 (TableExpression tables whs' grps' hvs' srts' lims' offs') = mconcat
474474 [ "FROM ", renderFromClause tables
475475 , renderWheres whs'
@@ -612,7 +612,7 @@ their placement in SQL.
612612-}
613613data FromClause schema params tables where
614614 Table
615− :: Aliased (Table (UnconstrainSchema schema)) table
615+ :: Aliased (Subtable (UnconstrainSchema schema)) table
616616 -> FromClause schema params '[table]
617617 Subquery
618618 :: Aliased (Query schema params) table
@@ -646,7 +646,7 @@ data FromClause schema params tables where
646646-- | Renders a `FromClause`.
647647renderFromClause :: FromClause schema params tables -> ByteString
648648renderFromClause = \case
649− Table table -> renderAliasedAs renderTable table
649+ Table table -> renderAliasedAs renderSubtable table
650650 Subquery selection -> renderAliasedAs (parenthesized . renderQuery) selection
651651 CrossJoin right left ->
652652 renderFromClause left <+> "CROSS JOIN" <+> renderFromClause right
@@ -672,11 +672,11 @@ data By
672672 (tables :: RelationProduct)
673673 (by :: (Symbol,Symbol)) where
674674 By
675− :: (HasUnique table tables columns, HasColumn column columns ty)
675+ :: (HasUnique table tables columns, Has column columns ty)
676676 => Alias column
677677 -> By tables '(table, column)
678678 By2
679− :: (HasTable table tables columns, HasColumn column columns ty)
679+ :: (Has table tables columns, Has column columns ty)
680680 => (Alias table, Alias column)
681681 -> By tables '(table, column)
682682deriving instance Show (By tables by)
squeal-postgresql/src/Squeal/PostgreSQL/Schema.hs+7−7
@@ -262,22 +262,22 @@ type family PGTypeOf (ty :: NullityType) :: PGType where
262262
263263-- | `SameTypes` is a constraint that proves two `ColumnsType`s have the same
264264-- length and the same `ColumnType`s.
265−type family SameTypes (columns0 :: RelationType) (columns1 :: RelationType)
265+type family SameTypes (columns0 :: ColumnsType) (columns1 :: ColumnsType)
266266 :: Constraint where
267267 SameTypes '[] '[] = ()
268− SameTypes (column0 ::: ty0 ': columns0) (column1 ::: ty1 ': columns1)
268+ SameTypes (column0 ::: def0 :=> ty0 ': columns0) (column1 ::: def1 :=> ty1 ': columns1)
269269 = (ty0 ~ ty1, SameTypes columns0 columns1)
270270
271271-- | `AllNotNull` is a constraint that proves a `ColumnsType` has no @NULL@s.
272−type family AllNotNull (columns :: RelationType) :: Constraint where
272+type family AllNotNull (columns :: ColumnsType) :: Constraint where
273273 AllNotNull '[] = ()
274− AllNotNull (column ::: 'NotNull ty ': columns) = AllNotNull columns
274+ AllNotNull (column ::: def :=> 'NotNull ty ': columns) = AllNotNull columns
275275
276276-- | `NotAllNull` is a constraint that proves a `ColumnsType` has some
277277-- @NOT NULL@.
278−type family NotAllNull (columns :: RelationType) :: Constraint where
279− NotAllNull (column ::: 'NotNull ty ': columns) = ()
280− NotAllNull (column ::: 'Null ty ': columns) = NotAllNull columns
278+type family NotAllNull (columns :: ColumnsType) :: Constraint where
279+ NotAllNull (column ::: def :=> 'NotNull ty ': columns) = ()
280+ NotAllNull (column ::: def :=> 'Null ty ': columns) = NotAllNull columns
281281
282282-- | `NullifyType` is an idempotent that nullifies a `ColumnType`.
283283type family NullifyType (ty :: NullityType) :: NullityType where