@@ -32,10 +32,12 @@ module Squeal.PostgreSQL.Definition
32 -- * Alter
32 -- * Alter
33 , alterTable
33 , alterTable
34 , alterTableRename
34 , alterTableRename
35+ , alterTableAddConstraint
35 , AlterColumns (UnsafeAlterColumns, renderAlterColumns)
36 , AlterColumns (UnsafeAlterColumns, renderAlterColumns)
36 , addColumnDefault
37 , addColumnDefault
37 , addColumnNull
38 , addColumnNull
38 , dropColumn
39 , dropColumn
39 , renameColumn
41 , renameColumn
40 , alterColumn
42 , alterColumn
41 , AlterColumn (UnsafeAlterColumn, renderAlterColumn)
43 , AlterColumn (UnsafeAlterColumn, renderAlterColumn)
@@ -150,7 +152,7 @@ check
150check condition = UnsafeTableConstraint $
152check condition = UnsafeTableConstraint $
151 "CHECK" <+> parenthesized (renderExpression condition)
153 "CHECK" <+> parenthesized (renderExpression condition)
153−-- | `unique` constraints ensure that the data contained in a column,
155+-- | A `unique` constraint ensure that the data contained in a column,
154-- or a group of columns, is unique among all the rows in the table.
156-- or a group of columns, is unique among all the rows in the table.
@@ -304,8 +306,8 @@ ALTER statements
304-- | `alterTable` changes the definition of a table from the schema.
306-- | `alterTable` changes the definition of a table from the schema.
305alterTable
307alterTable
306 :: HasTable table schema columns0
308 :: HasTable table schema columns0
307− => Alias table
309+ => Alias table -- ^ table to alter
308− -> AlterColumns columns0 columns1
310+ -> AlterColumns columns0 columns1 -- ^ alteration to perform
309 -> Definition schema (Alter table schema columns1)
311 -> Definition schema (Alter table schema columns1)
310alterTable table alteration = UnsafeDefinition $
312alterTable table alteration = UnsafeDefinition $
311 "ALTER TABLE"
313 "ALTER TABLE"
@@ -313,7 +315,7 @@ alterTable table alteration = UnsafeDefinition $
313 <+> renderAlterColumns alteration
315 <+> renderAlterColumns alteration
316−-- | `alterTable` changes the name of a table from the schema.
318+-- | `alterTableRename` changes the name of a table from the schema.
318-- >>> renderDefinition $ alterTableRename #foo #bar
320-- >>> renderDefinition $ alterTableRename #foo #bar
319-- "ALTER TABLE foo RENAME TO bar;"
321-- "ALTER TABLE foo RENAME TO bar;"
@@ -326,20 +328,71 @@ alterTableRename table0 table1 = UnsafeDefinition $
326 "ALTER TABLE" <+> renderAlias table0
328 "ALTER TABLE" <+> renderAlias table0
327 <+> "RENAME TO" <+> renderAlias table1 <> ";"
329 <+> "RENAME TO" <+> renderAlias table1 <> ";"
331+-- | An `alterTableAddConstraint` adds a table constraint.
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
341+-- "ALTER TABLE tab ADD check ((col > 0));"
342+alterTableAddConstraint
343+ :: HasTable table schema columns
345+ -> TableConstraint schema columns
346+ -> Definition schema schema
347+alterTableAddConstraint table constraint = UnsafeDefinition $
348+ "ALTER TABLE" <+> renderAlias table
349+ <+> "ADD" <+> renderTableConstraint constraint <> ";"
351+-- | An `AlterColumns` describes the alteration to perform on the columns
329newtype AlterColumns
353newtype AlterColumns
330 (columns0 :: ColumnsType)
354 (columns0 :: ColumnsType)
331 (columns1 :: ColumnsType) =
355 (columns1 :: ColumnsType) =
332 UnsafeAlterColumns {renderAlterColumns :: ByteString}
356 UnsafeAlterColumns {renderAlterColumns :: ByteString}
333 deriving (GHC.Generic,Show,Eq,Ord,NFData)
357 deriving (GHC.Generic,Show,Eq,Ord,NFData)
359+-- | An `addColumnDefault` adds a new `Optional` column. The new column is
360+-- initially filled with whatever default value is given.
364+-- definition :: Definition
365+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
367+-- '[ "col1" ::: 'Required ('Null 'PGint4)
368+-- , "col2" ::: 'Optional ('Null 'PGtext) ]]
369+-- definition = alterTable #tab
370+-- (addColumnDefault #col2 (text & default_ "foo"))
371+-- in renderDefinition definition
373+-- "ALTER TABLE tab ADD COLUMN col2 text DEFAULT E'foo';"
335addColumnDefault
374addColumnDefault
336 :: KnownSymbol column
375 :: KnownSymbol column
337− => Alias column
376+ => Alias column -- ^ column to add
338− -> TypeExpression ('Optional ty)
377+ -> TypeExpression ('Optional ty) -- ^ type of the new column
339 -> AlterColumns columns (Create column ('Optional ty) columns)
378 -> AlterColumns columns (Create column ('Optional ty) columns)
340addColumnDefault column ty = UnsafeAlterColumns $
379addColumnDefault column ty = UnsafeAlterColumns $
341 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
380 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
382+-- | An `addColumnDefault` adds a new `Null` column. The new column is
383+-- initially filled with %NULL%s.
387+-- definition :: Definition
388+-- '["tab" ::: '["col1" ::: 'Required ('Null 'PGint4)]]
390+-- '[ "col1" ::: 'Required ('Null 'PGint4)
391+-- , "col2" ::: 'Required ('Null 'PGtext) ]]
392+-- definition = alterTable #tab (addColumnNull #col2 text)
393+-- in renderDefinition definition
395+-- "ALTER TABLE tab ADD COLUMN col2 text;"
343addColumnNull
396addColumnNull
344 :: KnownSymbol column
397 :: KnownSymbol column
345 => Alias column
398 => Alias column
@@ -348,6 +401,22 @@ addColumnNull
348addColumnNull column ty = UnsafeAlterColumns $
401addColumnNull column ty = UnsafeAlterColumns $
349 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
402 "ADD COLUMN" <+> renderAlias column <+> renderTypeExpression ty
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.
411+-- definition :: Definition
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
419+-- "ALTER TABLE tab DROP COLUMN col2;"
351dropColumn
420dropColumn
352 :: KnownSymbol column
421 :: KnownSymbol column
353 => Alias column
422 => Alias column
@@ -355,6 +424,38 @@ dropColumn
355dropColumn column = UnsafeAlterColumns $
424dropColumn column = UnsafeAlterColumns $
356 "DROP COLUMN" <+> renderAlias column
425 "DROP COLUMN" <+> renderAlias column
427+-- | Like `dropColumn` but authorizes dropping everything that depends
432+-- definition :: Definition
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
440+-- "ALTER TABLE tab DROP COLUMN col2 CASCADE;"
442+ :: KnownSymbol column
444+ -> AlterColumns columns (Drop column columns)
445+dropColumnCascade column = UnsafeAlterColumns $
446+ "DROP COLUMN" <+> renderAlias column <+> "CASCADE"
448+-- | A `renameColumn` renames a column.
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
458+-- "ALTER TABLE tab RENAME COLUMN foo TO bar;"
358renameColumn
459renameColumn
359 :: (KnownSymbol column0, KnownSymbol column1)
460 :: (KnownSymbol column0, KnownSymbol column1)
360 => Alias column0
461 => Alias column0
@@ -363,6 +464,7 @@ renameColumn
363renameColumn column0 column1 = UnsafeAlterColumns $
464renameColumn column0 column1 = UnsafeAlterColumns $
364 "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
465 "RENAME COLUMN" <+> renderAlias column0 <+> "TO" <+> renderAlias column1
467+-- | An `alterColumn` alters a single column.
366alterColumn
468alterColumn
367 :: (KnownSymbol column, HasColumn column columns ty0)
469 :: (KnownSymbol column, HasColumn column columns ty0)
368 => Alias column
470 => Alias column
@@ -371,28 +473,89 @@ alterColumn
371alterColumn column alteration = UnsafeAlterColumns $
473alterColumn column alteration = UnsafeAlterColumns $
372 "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
474 "ALTER COLUMN" <+> renderAlias column <+> renderAlterColumn alteration
476+-- | An `AlterColumn` describes the alteration to perform on a single column.
374newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
477newtype AlterColumn (ty0 :: ColumnType) (ty1 :: ColumnType) =
375 UnsafeAlterColumn {renderAlterColumn :: ByteString}
478 UnsafeAlterColumn {renderAlterColumn :: ByteString}
376 deriving (GHC.Generic,Show,Eq,Ord,NFData)
479 deriving (GHC.Generic,Show,Eq,Ord,NFData)
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.
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
493+-- "ALTER TABLE tab ALTER COLUMN col SET DEFAULT 5;"
378setDefault
494setDefault
379 :: Expression '[] 'Ungrouped '[] ('Required ty)
495 :: Expression '[] 'Ungrouped '[] ('Required ty)
380− -> AlterColumn ('Required ty) ('Optional ty)
496+ -> AlterColumn (optionality ty) ('Optional ty)
381setDefault expression = UnsafeAlterColumn $
497setDefault expression = UnsafeAlterColumn $
382 "SET DEFAULT" <+> renderExpression expression
498 "SET DEFAULT" <+> renderExpression expression
384−dropDefault :: AlterColumn ('Optional ty) ('Required ty)
500+-- | A `dropDefault` removes any default value for a column.
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
510+-- "ALTER TABLE tab ALTER COLUMN col DROP DEFAULT;"
511+dropDefault :: AlterColumn (optionality ty) ('Required ty)
385dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
512dropDefault = UnsafeAlterColumn $ "DROP DEFAULT"
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.
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
526+-- "ALTER TABLE tab ALTER COLUMN col SET NOT NULL;"
387setNotNull
527setNotNull
388 :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
528 :: AlterColumn (optionality ('Null ty)) (optionality ('NotNull ty))
389setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
529setNotNull = UnsafeAlterColumn $ "SET NOT NULL"
531+-- | A `dropNotNull` drops a @NOT NULL@ constraint from a column.
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
541+-- "ALTER TABLE tab ALTER COLUMN col DROP NOT NULL;"
391dropNotNull
542dropNotNull
392 :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
543 :: AlterColumn (optionality ('NotNull ty)) (optionality ('Null ty))
393dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
544dropNotNull = UnsafeAlterColumn $ "DROP NOT NULL"
395−alterType
546+-- | An `alterType` converts a column to a different data type.
396− :: TypeExpression (optionality (nullity ty1))
547+-- This will succeed only if each existing entry in the column can be
397− -> AlterColumn (optionality (nullity ty0)) (optionality (nullity ty1))
548+-- converted to the new type by an implicit cast.
552+-- definition :: Definition
553+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGint4)]]
554+-- '["tab" ::: '["col" ::: 'Required ('NotNull 'PGnumeric)]]
556+-- alterTable #tab (alterColumn #col (alterType (numeric & notNull)))
557+-- in renderDefinition definition
559+-- "ALTER TABLE tab ALTER COLUMN col TYPE numeric;"
560+alterType :: TypeExpression ty -> AlterColumn ty0 ty1
398alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty
561alterType ty = UnsafeAlterColumn $ "TYPE " <> renderTypeExpression ty