on dev help sign in
table constraints
commit9d5c2b623b2b0f13d69b1312dd11d295697d16a0 authorEitan Chatav <eitan.chatav@gmail.com> dateThu 10 Aug 2017, 12:13 (9 years ago) parente1912e9
3 files changed+76−8
squeel-postgresql/exe/Example.hs+2−2 squeel-postgresql/src/Squeel/PostgreSQL/Statement.hs+70−4 squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+4−2
squeel-postgresql/exe/Example.hs+2−2
@@ -32,12 +32,12 @@ main = do
3232 connection1 <- flip execPQ (connection0 :: Connection '[]) $ pqExec $
3333 createTable #students
3434 ( (text & notNull) `As` #name
35− :* Nil )
35+ :* Nil ) []
3636 >>>
3737 createTable #table1
3838 ( (int4 & notNull) `As` #col1
3939 :* (int4 & notNull) `As` #col2
40− :* Nil )
40+ :* Nil ) []
4141 Char8.putStrLn "querying"
4242 connection2 <- flip execPQ (connection1 :: Connection Tables) $ do
4343 for_ [I i :* I (i+1) :* Nil | i <- [1::Int32,3..9]] $ pqExecParams
squeel-postgresql/src/Squeel/PostgreSQL/Statement.hs+70−4
@@ -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
squeel-postgresql/test/Squeel/PostgreSQL/StatementSpec.hs+4−2
@@ -226,7 +226,7 @@ spec = do
226226 \ CROSS JOIN orders AS orders2;"
227227 it "should render CREATE TABLE statements" $ do
228228 createTable #table1
229− ((int4 & notNull) `As` #col1 :* (int4 & notNull) `As` #col2 :* Nil)
229+ ((int4 & notNull) `As` #col1 :* (int4 & notNull) `As` #col2 :* Nil) []
230230 `definitionRenders`
231231 "CREATE TABLE table1\
232232 \ (col1 int4 NOT NULL, col2 int4 NOT NULL);"
@@ -234,11 +234,13 @@ spec = do
234234 ( serial `As` #col1 :*
235235 text `As` #col2 :*
236236 (int8 & notNull & default_ 8) `As` #col3 :* Nil )
237+ [check (#col3 >* 0)]
237238 `definitionRenders`
238239 "CREATE TABLE table2\
239240 \ (col1 serial,\
240241 \ col2 text,\
241− \ col3 int8 NOT NULL DEFAULT 8);"
242+ \ col3 int8 NOT NULL DEFAULT 8,\
243+ \ CHECK (col3 > 0));"
242244 it "should render DROP TABLE statements" $ do
243245 let
244246 statement :: Definition Tables '[]