@@ -866,14 +866,80 @@ createTable
866866 :: (KnownSymbol table, SListI columns)
867867 => Alias table
868868 -> NP (Aliased TypeExpression) columns
869+ -> [TableConstraint schema columns]
869870 -> Definition schema (Create table columns schema)
870−createTable table columns = UnsafeDefinition $
871+createTable table columns constraints = UnsafeDefinition $
871872 "CREATE TABLE" <+> renderAlias table
872− <+> parenthesized (renderCommaSeparated renderColumn columns) <> ";"
873+ <+> parenthesized
874+ ( renderCommaSeparated renderColumnDef columns
875+ <> renderConstraints constraints )
876+ <> ";"
873877 where
874− renderColumn :: Aliased TypeExpression x -> ByteString
875− renderColumn (ty `As` column) =
878+ renderColumnDef :: Aliased TypeExpression x -> ByteString
879+ renderColumnDef (ty `As` column) =
876880 renderAlias column <+> renderTypeExpression ty
881+ renderConstraints :: [TableConstraint schema columns] -> ByteString
882+ renderConstraints = \case
883+ [] -> ""
884+ _ -> ", " <> commaSeparated (renderTableConstraint <$> constraints)
885+
886+data TableConstraint
887+ (schema :: [(Symbol,[(Symbol,ColumnType)])])
888+ (columns :: [(Symbol,ColumnType)])
889+ = UnsafeTableConstraint { renderTableConstraint :: ByteString }
890+
891+check
892+ :: Condition '[] '[table ::: columns] 'Ungrouped
893+ -> TableConstraint schema columns
894+check condition = UnsafeTableConstraint $
895+ "CHECK" <+> renderExpression condition
896+
897+newtype Column
898+ (columns :: [(Symbol,ColumnType)])
899+ (columnty :: (Symbol,ColumnType))
900+ = UnsafeColumn {renderColumn :: ByteString}
901+instance HasColumn column columns ty
902+ => IsLabel column (Column columns (column ::: ty)) where
903+ fromLabel symbol = UnsafeColumn (renderSymbol symbol)
904+
905+unique
906+ :: SListI subcolumns
907+ => NP (Column columns) subcolumns
908+ -> TableConstraint schema columns
909+unique columns = UnsafeTableConstraint $
910+ "UNIQUE" <+> renderCommaSeparated renderColumn columns
911+
912+primaryKey
913+ :: (SListI subcolumns, NotNullTypes subcolumns)
914+ => NP (Column columns) subcolumns
915+ -> TableConstraint schema columns
916+primaryKey columns = UnsafeTableConstraint $
917+ "PRIMARY KEY" <+> renderCommaSeparated renderColumn columns
918+
919+type family SameTypes columns0 columns1 :: Constraint where
920+ SameTypes '[] '[] = ()
921+ SameTypes ((column0 ::: ty0) ': columns0) ((column1 ::: ty1) ': columns1)
922+ = (ty0 ~ ty1, SameTypes columns0 columns1)
923+
924+type family NotNullTypes columns :: Constraint where
925+ NotNullTypes '[] = ()
926+ NotNullTypes ((column ::: (optionality ('NotNull ty))) ': columns)
927+ = NotNullTypes columns
928+
929+foreignKey
930+ :: ( HasTable reftable schema refcolumns
931+ , SameTypes subcolumns refsubcolumns
932+ , NotNullTypes subcolumns
933+ , SListI subcolumns
934+ , SListI refsubcolumns)
935+ => NP (Column columns) subcolumns
936+ -> Alias reftable
937+ -> NP (Column refcolumns) refsubcolumns
938+ -> TableConstraint schema columns
939+foreignKey columns reftable refcolumns = UnsafeTableConstraint $
940+ "FOREIGN KEY" <+> parenthesized (renderCommaSeparated renderColumn columns)
941+ <+> "REFERENCES" <+> renderAlias reftable
942+ <+> parenthesized (renderCommaSeparated renderColumn refcolumns)
877943
878944{-----------------------------------------
879945DROP statements