-module(galchemy@schema@ddl@postgres). -compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]). -define(FILEPATH, "src\\galchemy\\schema\\ddl\\postgres.gleam"). -export([compile_operation/1, compile/1]). -export_type([ddl_compile_error/0]). -type ddl_compile_error() :: {empty_create_table_columns, galchemy@schema@diff:table_ref()} | {empty_primary_key_columns, binary()} | {empty_unique_constraint_columns, binary()} | {empty_foreign_key_columns, binary()} | {mismatched_foreign_key_columns, binary()}. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 410). -spec compile_identifier(binary()) -> binary(). compile_identifier(Identifier) -> <<<<"\""/utf8, (gleam@string:replace(Identifier, <<"\""/utf8>>, <<"\"\""/utf8>>))/binary>>/binary, "\""/utf8>>. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 394). -spec compile_custom_type_name(binary()) -> binary(). compile_custom_type_name(Name) -> _pipe = gleam@string:split(Name, <<"."/utf8>>), _pipe@1 = gleam@list:map(_pipe, fun compile_identifier/1), gleam@string:join(_pipe@1, <<"."/utf8>>). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 400). -spec compile_column_name_list(list(binary())) -> binary(). compile_column_name_list(Columns) -> _pipe = Columns, _pipe@1 = gleam@list:map(_pipe, fun compile_identifier/1), gleam@string:join(_pipe@1, <<", "/utf8>>). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 257). -spec compile_primary_key_clause(galchemy@schema@model:primary_key()) -> {ok, binary()} | {error, ddl_compile_error()}. compile_primary_key_clause(Primary_key) -> case erlang:element(3, Primary_key) of [] -> {error, {empty_primary_key_columns, erlang:element(2, Primary_key)}}; Columns -> {ok, <<<<<<<<"CONSTRAINT "/utf8, (compile_identifier( erlang:element(2, Primary_key) ))/binary>>/binary, " PRIMARY KEY ("/utf8>>/binary, (compile_column_name_list(Columns))/binary>>/binary, ")"/utf8>>} end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 273). -spec compile_unique_constraint_clause( galchemy@schema@model:unique_constraint() ) -> {ok, binary()} | {error, ddl_compile_error()}. compile_unique_constraint_clause(Constraint) -> case erlang:element(3, Constraint) of [] -> {error, {empty_unique_constraint_columns, erlang:element(2, Constraint)}}; Columns -> {ok, <<<<<<<<"CONSTRAINT "/utf8, (compile_identifier( erlang:element(2, Constraint) ))/binary>>/binary, " UNIQUE ("/utf8>>/binary, (compile_column_name_list(Columns))/binary>>/binary, ")"/utf8>>} end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 289). -spec compile_foreign_key_clause(galchemy@schema@model:foreign_key()) -> {ok, binary()} | {error, ddl_compile_error()}. compile_foreign_key_clause(Foreign_key) -> case {erlang:element(3, Foreign_key), erlang:element(6, Foreign_key)} of {[], _} -> {error, {empty_foreign_key_columns, erlang:element(2, Foreign_key)}}; {_, []} -> {error, {empty_foreign_key_columns, erlang:element(2, Foreign_key)}}; {Left, Right} -> case erlang:length(Left) =:= erlang:length(Right) of false -> {error, {mismatched_foreign_key_columns, erlang:element(2, Foreign_key)}}; true -> {ok, <<<<<<<<<<<<<<<<<<<<"CONSTRAINT "/utf8, (compile_identifier( erlang:element( 2, Foreign_key ) ))/binary>>/binary, " FOREIGN KEY ("/utf8>>/binary, (compile_column_name_list( erlang:element( 3, Foreign_key ) ))/binary>>/binary, ") REFERENCES "/utf8>>/binary, (compile_identifier( erlang:element( 4, Foreign_key ) ))/binary>>/binary, "."/utf8>>/binary, (compile_identifier( erlang:element(5, Foreign_key) ))/binary>>/binary, " ("/utf8>>/binary, (compile_column_name_list( erlang:element(6, Foreign_key) ))/binary>>/binary, ")"/utf8>>} end end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 406). -spec compile_table_ref(galchemy@schema@diff:table_ref()) -> binary(). compile_table_ref(Ref) -> <<<<(compile_identifier(erlang:element(2, Ref)))/binary, "."/utf8>>/binary, (compile_identifier(erlang:element(3, Ref)))/binary>>. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 414). -spec int_to_string(integer()) -> binary(). int_to_string(Value) -> erlang:integer_to_binary(Value). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 381). -spec compile_numeric_type( gleam@option:option(integer()), gleam@option:option(integer()) ) -> binary(). compile_numeric_type(Precision, Scale) -> case {Precision, Scale} of {{some, Precision@1}, {some, Scale@1}} -> <<<<<<<<"NUMERIC("/utf8, (int_to_string(Precision@1))/binary>>/binary, ", "/utf8>>/binary, (int_to_string(Scale@1))/binary>>/binary, ")"/utf8>>; {{some, Precision@2}, none} -> <<<<"NUMERIC("/utf8, (int_to_string(Precision@2))/binary>>/binary, ")"/utf8>>; {none, _} -> <<"NUMERIC"/utf8>> end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 345). -spec compile_column_type(galchemy@schema@model:column_type()) -> binary(). compile_column_type(Column_type) -> case Column_type of small_int_type -> <<"SMALLINT"/utf8>>; integer_type -> <<"INTEGER"/utf8>>; big_int_type -> <<"BIGINT"/utf8>>; boolean_type -> <<"BOOLEAN"/utf8>>; text_type -> <<"TEXT"/utf8>>; {var_char_type, Length} -> case Length of {some, Length@1} -> <<<<"VARCHAR("/utf8, (int_to_string(Length@1))/binary>>/binary, ")"/utf8>>; none -> <<"VARCHAR"/utf8>> end; {timestamp_type, With_time_zone} -> case With_time_zone of true -> <<"TIMESTAMP WITH TIME ZONE"/utf8>>; false -> <<"TIMESTAMP WITHOUT TIME ZONE"/utf8>> end; {time_type, With_time_zone@1} -> case With_time_zone@1 of true -> <<"TIME WITH TIME ZONE"/utf8>>; false -> <<"TIME WITHOUT TIME ZONE"/utf8>> end; date_type -> <<"DATE"/utf8>>; real_type -> <<"REAL"/utf8>>; double_precision_type -> <<"DOUBLE PRECISION"/utf8>>; {numeric_type, Precision, Scale} -> compile_numeric_type(Precision, Scale); json_type -> <<"JSON"/utf8>>; jsonb_type -> <<"JSONB"/utf8>>; uuid_type -> <<"UUID"/utf8>>; bytea_type -> <<"BYTEA"/utf8>>; {array_type, Item_type} -> <<(compile_column_type(Item_type))/binary, "[]"/utf8>>; {custom_type, Name} -> compile_custom_type_name(Name) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 214). -spec compile_alter_column( galchemy@schema@diff:table_ref(), binary(), galchemy@schema@model:column_schema(), galchemy@schema@model:column_schema() ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_alter_column(Ref, Column_name, Current, Target) -> Base = <<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref))/binary>>/binary, " ALTER COLUMN "/utf8>>, Name = compile_identifier(Column_name), Type_statements = case erlang:element(3, Current) =:= erlang:element( 3, Target ) of true -> []; false -> [<<<<<>/binary, " TYPE "/utf8>>/binary, (compile_column_type(erlang:element(3, Target)))/binary>>] end, Default_statements = case {erlang:element(5, Current), erlang:element(5, Target)} of {none, none} -> []; {{some, Current_default}, {some, Target_default}} -> case Current_default =:= Target_default of true -> []; false -> [<<<<<>/binary, " SET DEFAULT "/utf8>>/binary, Target_default/binary>>] end; {none, {some, Target_default@1}} -> [<<<<<>/binary, " SET DEFAULT "/utf8>>/binary, Target_default@1/binary>>]; {{some, _}, none} -> [<<<>/binary, " DROP DEFAULT"/utf8>>] end, Nullability_statements = case erlang:element(4, Current) =:= erlang:element( 4, Target ) of true -> []; false -> case erlang:element(4, Target) of true -> [<<<>/binary, " DROP NOT NULL"/utf8>>]; false -> [<<<>/binary, " SET NOT NULL"/utf8>>] end end, {ok, lists:append( lists:append(Type_statements, Default_statements), Nullability_statements )}. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 327). -spec compile_column_definition(galchemy@schema@model:column_schema()) -> binary(). compile_column_definition(Column) -> Default_sql = case erlang:element(5, Column) of none -> <<""/utf8>>; {some, Default} -> <<" DEFAULT "/utf8, Default/binary>> end, Nullability_sql = case erlang:element(4, Column) of true -> <<""/utf8>>; false -> <<" NOT NULL"/utf8>> end, <<<<<<<<(compile_identifier(erlang:element(2, Column)))/binary, " "/utf8>>/binary, (compile_column_type(erlang:element(3, Column)))/binary>>/binary, Default_sql/binary>>/binary, Nullability_sql/binary>>. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 418). -spec result_try( {ok, OJM} | {error, OJN}, fun((OJM) -> {ok, OJQ} | {error, OJN}) ) -> {ok, OJQ} | {error, OJN}. result_try(Result, Next) -> case Result of {ok, Value} -> Next(Value); {error, Error} -> {error, Error} end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 140). -spec compile_create_table_primary_key( gleam@option:option(galchemy@schema@model:primary_key()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_create_table_primary_key(Primary_key) -> case Primary_key of none -> {ok, []}; {some, Primary_key@1} -> result_try( compile_primary_key_clause(Primary_key@1), fun(Clause) -> {ok, [Clause]} end ) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 190). -spec compile_add_primary_key( galchemy@schema@diff:table_ref(), galchemy@schema@model:primary_key() ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_add_primary_key(Ref, Primary_key) -> result_try( compile_primary_key_clause(Primary_key), fun(Clause) -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref))/binary>>/binary, " ADD "/utf8>>/binary, Clause/binary>>]} end ). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 198). -spec compile_add_unique_constraint( galchemy@schema@diff:table_ref(), galchemy@schema@model:unique_constraint() ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_add_unique_constraint(Ref, Constraint) -> result_try( compile_unique_constraint_clause(Constraint), fun(Clause) -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref))/binary>>/binary, " ADD "/utf8>>/binary, Clause/binary>>]} end ). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 206). -spec compile_add_foreign_key( galchemy@schema@diff:table_ref(), galchemy@schema@model:foreign_key() ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_add_foreign_key(Ref, Foreign_key) -> result_try( compile_foreign_key_clause(Foreign_key), fun(Clause) -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref))/binary>>/binary, " ADD "/utf8>>/binary, Clause/binary>>]} end ). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 425). -spec reverse_append(list(OJV), list(OJV)) -> list(OJV). reverse_append(Items, Acc) -> case Items of [] -> Acc; [Item | Rest] -> reverse_append(Rest, [Item | Acc]) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 436). -spec reverse_loop(list(OKC), list(OKC)) -> list(OKC). reverse_loop(Items, Acc) -> case Items of [] -> Acc; [Item | Rest] -> reverse_loop(Rest, [Item | Acc]) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 432). -spec reverse(list(OJZ)) -> list(OJZ). reverse(Items) -> reverse_loop(Items, []). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 164). -spec compile_unique_constraint_clauses( list(galchemy@schema@model:unique_constraint()), list(binary()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_unique_constraint_clauses(Constraints, Acc) -> case Constraints of [] -> {ok, reverse(Acc)}; [Constraint | Rest] -> result_try( compile_unique_constraint_clause(Constraint), fun(Clause) -> compile_unique_constraint_clauses(Rest, [Clause | Acc]) end ) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 152). -spec compile_create_table_unique_constraints( list(galchemy@schema@model:unique_constraint()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_create_table_unique_constraints(Constraints) -> compile_unique_constraint_clauses(Constraints, []). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 177). -spec compile_foreign_key_clauses( list(galchemy@schema@model:foreign_key()), list(binary()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_foreign_key_clauses(Foreign_keys, Acc) -> case Foreign_keys of [] -> {ok, reverse(Acc)}; [Foreign_key | Rest] -> result_try( compile_foreign_key_clause(Foreign_key), fun(Clause) -> compile_foreign_key_clauses(Rest, [Clause | Acc]) end ) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 158). -spec compile_create_table_foreign_keys( list(galchemy@schema@model:foreign_key()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_create_table_foreign_keys(Foreign_keys) -> compile_foreign_key_clauses(Foreign_keys, []). -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 317). -spec table_index_definitions( list(galchemy@schema@model:index_schema()), list(binary()) ) -> list(binary()). table_index_definitions(Indexes, Acc) -> case Indexes of [] -> reverse(Acc); [Index | Rest] -> table_index_definitions(Rest, [erlang:element(4, Index) | Acc]) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 101). -spec compile_create_table(galchemy@schema@model:table_schema()) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_create_table(Table) -> Ref = {table_ref, erlang:element(2, Table), erlang:element(3, Table)}, case erlang:element(4, Table) of [] -> {error, {empty_create_table_columns, Ref}}; _ -> result_try( compile_create_table_primary_key(erlang:element(5, Table)), fun(Primary_key_sql) -> result_try( compile_create_table_unique_constraints( erlang:element(6, Table) ), fun(Unique_constraints_sql) -> result_try( compile_create_table_foreign_keys( erlang:element(7, Table) ), fun(Foreign_keys_sql) -> Column_sql = gleam@list:map( erlang:element(4, Table), fun compile_column_definition/1 ), Parts = lists:append( [Column_sql, Primary_key_sql, Unique_constraints_sql, Foreign_keys_sql] ), Create_table_sql = <<<<<<<<"CREATE TABLE "/utf8, (compile_table_ref(Ref))/binary>>/binary, " ("/utf8>>/binary, (gleam@string:join( Parts, <<", "/utf8>> ))/binary>>/binary, ")"/utf8>>, {ok, [Create_table_sql | table_index_definitions( erlang:element(8, Table), [] )]} end ) end ) end ) end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 22). -spec compile_operation(galchemy@schema@diff:schema_operation()) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_operation(Operation) -> case Operation of {create_table, Table} -> compile_create_table(Table); {drop_table, Ref} -> {ok, [<<"DROP TABLE "/utf8, (compile_table_ref(Ref))/binary>>]}; {add_column, Ref@1, Column} -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref@1))/binary>>/binary, " ADD COLUMN "/utf8>>/binary, (compile_column_definition(Column))/binary>>]}; {drop_column, Ref@2, Column_name} -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref@2))/binary>>/binary, " DROP COLUMN "/utf8>>/binary, (compile_identifier(Column_name))/binary>>]}; {alter_column, Ref@3, Column_name@1, Current, Target} -> compile_alter_column(Ref@3, Column_name@1, Current, Target); {add_primary_key, Ref@4, Primary_key} -> compile_add_primary_key(Ref@4, Primary_key); {drop_primary_key, Ref@5, Primary_key_name} -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref@5))/binary>>/binary, " DROP CONSTRAINT "/utf8>>/binary, (compile_identifier(Primary_key_name))/binary>>]}; {add_unique_constraint, Ref@6, Constraint} -> compile_add_unique_constraint(Ref@6, Constraint); {drop_unique_constraint, Ref@7, Constraint_name} -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref@7))/binary>>/binary, " DROP CONSTRAINT "/utf8>>/binary, (compile_identifier(Constraint_name))/binary>>]}; {add_foreign_key, Ref@8, Foreign_key} -> compile_add_foreign_key(Ref@8, Foreign_key); {drop_foreign_key, Ref@9, Foreign_key_name} -> {ok, [<<<<<<"ALTER TABLE "/utf8, (compile_table_ref(Ref@9))/binary>>/binary, " DROP CONSTRAINT "/utf8>>/binary, (compile_identifier(Foreign_key_name))/binary>>]}; {add_index, _, Index} -> {ok, [erlang:element(4, Index)]}; {drop_index, Ref@10, Index_name} -> {ok, [<<<<<<"DROP INDEX "/utf8, (compile_identifier(erlang:element(2, Ref@10)))/binary>>/binary, "."/utf8>>/binary, (compile_identifier(Index_name))/binary>>]} end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 86). -spec compile_loop( list(galchemy@schema@diff:schema_operation()), list(binary()) ) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile_loop(Operations, Acc) -> case Operations of [] -> {ok, reverse(Acc)}; [Operation | Rest] -> case compile_operation(Operation) of {ok, Statements} -> compile_loop(Rest, reverse_append(Statements, Acc)); {error, Error} -> {error, Error} end end. -file("src\\galchemy\\schema\\ddl\\postgres.gleam", 16). -spec compile(list(galchemy@schema@diff:schema_operation())) -> {ok, list(binary())} | {error, ddl_compile_error()}. compile(Operations) -> compile_loop(Operations, []).