on dev help sign in
docs
commitef66497fffca5dc9dffc4975c1ecf6d4139cd0da authorEitan Chatav <eitan.chatav@gmail.com> dateMon 21 Aug 2017, 11:42 (9 years ago) parentb62330c
1 file changed+174−11
squeal-postgresql/src/Squeal/PostgreSQL/Definition.hs+174−11
squeal-postgresql/src/Squeal/PostgreSQL/Definition.hs+174−11
@@ -32,10 +32,12 @@ module Squeal.PostgreSQL.Definition
3232 -- * Alter
3333 , alterTable
3434 , alterTableRename
35+ , alterTableAddConstraint
3536 , AlterColumns (UnsafeAlterColumns, renderAlterColumns)
3637 , addColumnDefault
3738 , addColumnNull
3839 , dropColumn
40+ , dropColumnCascade
3941 , renameColumn
4042 , alterColumn
4143 , AlterColumn (UnsafeAlterColumn, renderAlterColumn)
@@ -150,7 +152,7 @@ check
150152check condition = UnsafeTableConstraint $
151153 "CHECK" <+> parenthesized (renderExpression condition)
152154
153−-- | `unique` constraints ensure that the data contained in a column,
155+-- | A `unique` constraint ensure that the data contained in a column,
154156-- or a group of columns, is unique among all the rows in the table.
155157--
156158-- >>> :{
@@ -304,8 +306,8 @@ ALTER statements
304306-- | `alterTable` changes the definition of a table from the schema.
305307alterTable
306308 :: HasTable table schema columns0
307− => Alias table
308− -> AlterColumns columns0 columns1
309+ => Alias table -- ^ table to alter
310+ -> AlterColumns columns0 columns1 -- ^ alteration to perform
309311 -> Definition schema (Alter table schema columns1)
310312alterTable table alteration = UnsafeDefinition $
311313 "ALTER TABLE"
@@ -313,7 +315,7 @@ alterTable table alteration = UnsafeDefinition $
313315 <+> renderAlterColumns alteration
314316 <> ";"
315317
316−-- | `alterTable` changes the name of a table from the schema.
318+-- | `alterTableRename` changes the name of a table from the schema.
317319--
318320-- >>> renderDefinition $ alterTableRename #foo #bar
319321-- "ALTER TABLE foo RENAME TO bar;"
@@ -326,20 +328,71 @@ alterTableRename table0 table1 = UnsafeDefinition $
326328 "ALTER TABLE" <+> renderAlias table0
327329 <+> "RENAME TO" <+> renderAlias table1 <> ";"
328330
331+-- | An `alterTableAddConstraint` adds a table constraint.
332+--
333+-- >>> :{
334+-- let
335+-- definition :: Definition
336+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
337+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
338+-- definition = alterTableAddConstraint #tab (check (#col .> 0))
339+-- in renderDefinition definition
340+-- :}
341+-- "ALTER TABLE tab ADD check ((col > 0));"
342+alterTableAddConstraint
343+ :: HasTable table schema columns
344+ => Alias table
345+ -> TableConstraint schema columns
346+ -> Definition schema schema
347+alterTableAddConstraint table constraint = UnsafeDefinition $
348+ "ALTER TABLE" <+> renderAlias table
349+ <+> "ADD" <+> renderTableConstraint constraint <> ";"
350+
351+-- | An `AlterColumns` describes the alteration to perform on the columns
352+-- of a table.
329353newtype AlterColumns
330354 (columns0 :: ColumnsType)
331355 (columns1 :: ColumnsType) =
332356 UnsafeAlterColumns {renderAlterColumns :: ByteString}
333357 deriving (GHC.Generic,Show,Eq,Ord,NFData)
334358
359+-- | An `addColumnDefault` adds a new `Optional` column. The new column is
360+-- initially filled with whatever default value is given.
361+--
362+-- >>> :{
363+-- let
364+-- definition :: Definition
365+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
366+-- '["tab" :::
367+-- '[ "col1" ::: 'Required ('Null 'PGint4)
368+-- , "col2" ::: 'Optional ('Null 'PGtext) ]]
369+-- definition = alterTable #tab
370+-- (addColumnDefault #col2 (text & default_ "foo"))
371+-- in renderDefinition definition
372+-- :}
373+-- "ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';"
335374addColumnDefault
336375 :: KnownSymbol column
337− => Alias column
338− -> TypeExpression ('Optional ty)
376+ => Alias column -- ^ column to add
377+ -> TypeExpression ('Optional ty) -- ^ type of the new column
339378 -> AlterColumns columns (Create column ('Optional ty) columns)
340379addColumnDefault column ty = UnsafeAlterColumns $
341380 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
342381
382+-- | An `addColumnDefault` adds a new `Null` column. The new column is
383+-- initially filled with %NULL%s.
384+--
385+-- >>> :{
386+-- let
387+-- definition :: Definition
388+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
389+-- '["tab" :::
390+-- '[ "col1" ::: 'Required ('Null 'PGint4)
391+-- , "col2" ::: 'Required ('Null 'PGtext) ]]
392+-- definition = alterTable #tab (addColumnNull #col2 text)
393+-- in renderDefinition definition
394+-- :}
395+-- "ALTER TABLE tab ADD COLUMN col2 text;"
343396addColumnNull
344397 :: KnownSymbol column
345398 => Alias column
@@ -348,6 +401,22 @@ addColumnNull
348401addColumnNull column ty = UnsafeAlterColumns $
349402 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
350403
404+-- | A `dropColumn` removes a column. Whatever data was in the column
405+-- disappears. Table constraints involving the column are dropped, too.
406+-- However, if the column is referenced by a foreign key constraint of
407+-- another table, PostgreSQL will not silently drop that constraint.
408+--
409+-- >>> :{
410+-- let
411+-- definition :: Definition
412+-- '["tab" :::
413+-- '[ "col1" ::: 'Required ('Null 'PGint4)
414+-- , "col2" ::: 'Required ('Null 'PGtext) ]]
415+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
416+-- definition = alterTable #tab (dropColumn #col2)
417+-- in renderDefinition definition
418+-- :}
419+-- "ALTER TABLE tab DROP COLUMN col2;"
351420dropColumn
352421 :: KnownSymbol column
353422 => Alias column
@@ -355,6 +424,38 @@ dropColumn
355424dropColumn column = UnsafeAlterColumns $
356425 "DROP COLUMN" <+> renderAlias column
357426
427+-- | Like `dropColumn` but authorizes dropping everything that depends
428+-- on the column.
429+--
430+-- >>> :{
431+-- let
432+-- definition :: Definition
433+-- '["tab" :::
434+-- '[ "col1" ::: 'Required ('Null 'PGint4)
435+-- , "col2" ::: 'Required ('Null 'PGtext) ]]
436+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
437+-- definition = alterTable #tab (dropColumnCascade #col2)
438+-- in renderDefinition definition
439+-- :}
440+-- "ALTER TABLE tab DROP COLUMN col2 CASCADE;"
441+dropColumnCascade
442+ :: KnownSymbol column
443+ => Alias column
444+ -> AlterColumns columns (Drop column columns)
445+dropColumnCascade column = UnsafeAlterColumns $
446+ "DROP COLUMN" <+> renderAlias column <+> "CASCADE"
447+
448+-- | A `renameColumn` renames a column.
449+--
450+-- >>> :{
451+-- let
452+-- definition :: Definition
453+-- '["tab" ::: '["foo" ::: 'Required ('Null 'PGint4)]]
454+-- '["tab" ::: '["bar" ::: 'Required ('Null 'PGint4)]]
455+-- definition = alterTable #tab (renameColumn #foo #bar)
456+-- in renderDefinition definition
457+-- :}
458+-- "ALTER TABLE tab RENAME COLUMN foo TO bar;"
358459renameColumn
359460 :: (KnownSymbol column0, KnownSymbol column1)
360461 => Alias column0
@@ -363,6 +464,7 @@ renameColumn
363464renameColumn column0 column1 = UnsafeAlterColumns $
364465 "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
365466
467+-- | An `alterColumn` alters a single column.
366468alterColumn
367469 :: (KnownSymbol column, HasColumn column columns ty0)
368470 => Alias column
@@ -371,28 +473,89 @@ alterColumn
371473alterColumn column alteration = UnsafeAlterColumns $
372474 "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
373475
476+-- | An `AlterColumn` describes the alteration to perform on a single column.
374477newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
375478 UnsafeAlterColumn {renderAlterColumn :: ByteString}
376479 deriving (GHC.Generic,Show,Eq,Ord,NFData)
377480
481+-- | A `setDefault` sets a new default for a column. Note that this doesn't
482+-- affect any existing rows in the table, it just changes the default for
483+-- future `insertTable` and `updateTable` commands.
484+--
485+-- >>> :{
486+-- let
487+-- definition :: Definition
488+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
489+-- '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
490+-- definition = alterTable #tab (alterColumn #col (setDefault 5))
491+-- in renderDefinition definition
492+-- :}
493+-- "ALTER TABLE tab ALTER COLUMN col SET DEFAULT 5;"
378494setDefault
379495 :: Expression '[] 'Ungrouped '[] ('Required ty)
380− -> AlterColumn ('Required ty) ('Optional ty)
496+ -> AlterColumn (optionality ty) ('Optional ty)
381497setDefault expression = UnsafeAlterColumn $
382498 "SET DEFAULT" <+> renderExpression expression
383499
384−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
500+-- | A `dropDefault` removes any default value for a column.
501+--
502+-- >>> :{
503+-- let
504+-- definition :: Definition
505+-- '["tab" ::: '["col" ::: 'Optional ('Null 'PGint4)]]
506+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
507+-- definition = alterTable #tab (alterColumn #col dropDefault)
508+-- in renderDefinition definition
509+-- :}
510+-- "ALTER TABLE tab ALTER COLUMN col DROP DEFAULT;"
511+dropDefault :: AlterColumn (optionality ty) ('Required ty)
385512dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
386513
514+-- | A `setNotNull` adds a @NOT NULL@ constraint to a column.
515+-- The constraint will be checked immediately, so the table data must satisfy
516+-- the constraint before it can be added.
517+--
518+-- >>> :{
519+-- let
520+-- definition :: Definition
521+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
522+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
523+-- definition = alterTable #tab (alterColumn #col setNotNull)
524+-- in renderDefinition definition
525+-- :}
526+-- "ALTER TABLE tab ALTER COLUMN col SET NOT NULL;"
387527setNotNull
388528 :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
389529setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
390530
531+-- | A `dropNotNull` drops a @NOT NULL@ constraint from a column.
532+--
533+-- >>> :{
534+-- let
535+-- definition :: Definition
536+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
537+-- '["tab" ::: '["col" ::: 'Required ('Null 'PGint4)]]
538+-- definition = alterTable #tab (alterColumn #col dropNotNull)
539+-- in renderDefinition definition
540+-- :}
541+-- "ALTER TABLE tab ALTER COLUMN col DROP NOT NULL;"
391542dropNotNull
392543 :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
393544dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
394545
395−alterType
396− :: TypeExpression (optionality (nullity ty1))
397− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
546+-- | An `alterType` converts a column to a different data type.
547+-- This will succeed only if each existing entry in the column can be
548+-- converted to the new type by an implicit cast.
549+--
550+-- >>> :{
551+-- let
552+-- definition :: Definition
553+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
554+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGnumeric)]]
555+-- definition =
556+-- alterTable #tab (alterColumn #col (alterType (numeric & notNull)))
557+-- in renderDefinition definition
558+-- :}
559+-- "ALTER TABLE tab ALTER COLUMN col TYPE numeric;"
560+alterType :: TypeExpression ty -> AlterColumn ty0 ty1
398561alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty