@@ -78,6 +78,18 @@ if Code.ensure_loaded?(MyXQL) do
7878 end
7979 end
8080
81+ def to_constraints (
82+ % MyXQL.Error { mysql: % { name: :ER_CHECK_CONSTRAINT_VIOLATED } , message: message } ,
83+ _opts
84+ ) do
85+ with [ _ , quoted ] <- :binary . split ( message , [ "Check constraint " ] ) ,
86+ [ _ , constraint | _ ] <- :binary . split ( quoted , @ quotes , [ :global ] ) do
87+ [ check: constraint ]
88+ else
89+ _ -> [ ]
90+ end
91+ end
92+
8193 def to_constraints ( _ , _ ) ,
8294 do: [ ]
8395
@@ -1026,12 +1038,31 @@ if Code.ensure_loaded?(MyXQL) do
10261038 def execute_ddl ( { :create_if_not_exists , % Index { } } ) ,
10271039 do: error! ( nil , "MySQL adapter does not support create if not exists for index" )
10281040
1029- def execute_ddl ( { :create , % Constraint { check: check } } ) when is_binary ( check ) ,
1030- do: error! ( nil , "MySQL adapter does not support check constraints" )
1041+ def execute_ddl ( { :create , % Constraint { check: check } = constraint } ) when is_binary ( check ) do
1042+ table_name = quote_name ( constraint . prefix , constraint . table )
1043+ [ [ "ALTER TABLE " , table_name , " ADD " , new_constraint_expr ( constraint ) ] ]
1044+ end
10311045
10321046 def execute_ddl ( { :create , % Constraint { exclude: exclude } } ) when is_binary ( exclude ) ,
10331047 do: error! ( nil , "MySQL adapter does not support exclusion constraints" )
10341048
1049+ def execute_ddl ( { :drop , % Constraint { } , :cascade } ) ,
1050+ do: error! ( nil , "MySQL does not support `CASCADE` in `DROP CONSTRAINT` commands" )
1051+
1052+ def execute_ddl ( { :drop , % Constraint { } = constraint , _ } ) do
1053+ [
1054+ [
1055+ "ALTER TABLE " ,
1056+ quote_name ( constraint . prefix , constraint . table ) ,
1057+ " DROP CONSTRAINT " ,
1058+ quote_name ( constraint . name )
1059+ ]
1060+ ]
1061+ end
1062+
1063+ def execute_ddl ( { :drop_if_exists , % Constraint { } , _ } ) ,
1064+ do: error! ( nil , "MySQL adapter does not support `drop_if_exists` for constraints" )
1065+
10351066 def execute_ddl ( { :drop , % Index { } , :cascade } ) ,
10361067 do: error! ( nil , "MySQL adapter does not support cascade in drop index" )
10371068
@@ -1047,12 +1078,6 @@ if Code.ensure_loaded?(MyXQL) do
10471078 ]
10481079 end
10491080
1050- def execute_ddl ( { :drop , % Constraint { } , _ } ) ,
1051- do: error! ( nil , "MySQL adapter does not support constraints" )
1052-
1053- def execute_ddl ( { :drop_if_exists , % Constraint { } , _ } ) ,
1054- do: error! ( nil , "MySQL adapter does not support constraints" )
1055-
10561081 def execute_ddl ( { :drop_if_exists , % Index { } , _ } ) ,
10571082 do: error! ( nil , "MySQL adapter does not support drop if exists for index" )
10581083
@@ -1244,6 +1269,17 @@ if Code.ensure_loaded?(MyXQL) do
12441269 defp null_expr ( true ) , do: " NULL"
12451270 defp null_expr ( _ ) , do: [ ]
12461271
1272+ defp new_constraint_expr ( % Constraint { check: check } = constraint ) when is_binary ( check ) do
1273+ [
1274+ "CONSTRAINT " ,
1275+ quote_name ( constraint . name ) ,
1276+ " CHECK (" ,
1277+ check ,
1278+ ")" ,
1279+ validate ( constraint . validate )
1280+ ]
1281+ end
1282+
12471283 defp default_expr ( { :ok , nil } ) ,
12481284 do: " DEFAULT NULL"
12491285
@@ -1401,6 +1437,9 @@ if Code.ensure_loaded?(MyXQL) do
14011437 defp reference_on_update ( :restrict ) , do: " ON UPDATE RESTRICT"
14021438 defp reference_on_update ( _ ) , do: [ ]
14031439
1440+ defp validate ( false ) , do: " NOT ENFORCED"
1441+ defp validate ( _ ) , do: [ ]
1442+
14041443 ## Helpers
14051444
14061445 defp get_source ( query , sources , ix , source ) do
@@ -1423,6 +1462,10 @@ if Code.ensure_loaded?(MyXQL) do
14231462
14241463 defp maybe_add_column_names ( _ , name ) , do: name
14251464
1465+ defp quote_name ( nil , name ) , do: quote_name ( name )
1466+
1467+ defp quote_name ( prefix , name ) , do: [ quote_name ( prefix ) , ?. , quote_name ( name ) ]
1468+
14261469 defp quote_name ( name ) when is_atom ( name ) do
14271470 quote_name ( Atom . to_string ( name ) )
14281471 end
0 commit comments