Packages

SQL query builder core for Gleam

Current section

Files

Jump to
galchemy src galchemy@schema@introspection@postgres.erl
Raw

src/galchemy@schema@introspection@postgres.erl

-module(galchemy@schema@introspection@postgres).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src\\galchemy\\schema\\introspection\\postgres.gleam").
-export([default_options/0, only_schemas/2, include_system_schemas/1, column_row_decoder/0, index_row_decoder/0, constraint_row_decoder/0, compile_columns_query/1, compile_query/1, compile_constraints_query/1, compile_indexes_query/1, to_columns_query/1, to_query/1, to_constraints_query/1, to_indexes_query/1, rows_to_snapshot/3, introspect/2]).
-export_type([introspection_options/0, column_row/0, constraint_kind/0, constraint_row/0, index_row/0, introspection_error/0]).
-type introspection_options() :: {introspection_options,
list(binary()),
boolean()}.
-type column_row() :: {column_row,
binary(),
binary(),
binary(),
integer(),
boolean(),
binary(),
binary(),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(integer()),
gleam@option:option(binary())}.
-type constraint_kind() :: primary_key_constraint |
unique_constraint |
foreign_key_constraint.
-type constraint_row() :: {constraint_row,
binary(),
binary(),
binary(),
constraint_kind(),
binary(),
integer(),
gleam@option:option(binary()),
gleam@option:option(binary()),
gleam@option:option(binary())}.
-type index_row() :: {index_row,
binary(),
binary(),
binary(),
boolean(),
binary()}.
-type introspection_error() :: {columns_query_error, pog:query_error()} |
{constraints_query_error, pog:query_error()} |
{indexes_query_error, pog:query_error()}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 68).
-spec default_options() -> introspection_options().
default_options() ->
{introspection_options, [], false}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 72).
-spec only_schemas(introspection_options(), list(binary())) -> introspection_options().
only_schemas(Options, Schemas) ->
{introspection_options, Schemas, erlang:element(3, Options)}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 79).
-spec include_system_schemas(introspection_options()) -> introspection_options().
include_system_schemas(Options) ->
{introspection_options, erlang:element(2, Options), true}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 255).
-spec column_row_decoder() -> gleam@dynamic@decode:decoder(column_row()).
column_row_decoder() ->
_pipe = gleam@dynamic@decode:at(
[0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe,
fun(Schema_name) ->
_pipe@1 = gleam@dynamic@decode:at(
[1],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@1,
fun(Table_name) ->
_pipe@2 = gleam@dynamic@decode:at(
[2],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@2,
fun(Column_name) ->
_pipe@3 = gleam@dynamic@decode:at(
[3],
{decoder, fun gleam@dynamic@decode:decode_int/1}
),
gleam@dynamic@decode:then(
_pipe@3,
fun(Ordinal_position) ->
_pipe@4 = gleam@dynamic@decode:at(
[4],
{decoder,
fun gleam@dynamic@decode:decode_bool/1}
),
gleam@dynamic@decode:then(
_pipe@4,
fun(Is_nullable) ->
_pipe@5 = gleam@dynamic@decode:at(
[5],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@5,
fun(Data_type) ->
_pipe@6 = gleam@dynamic@decode:at(
[6],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@6,
fun(Udt_name) ->
_pipe@7 = gleam@dynamic@decode:at(
[7],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_int/1}
)
),
gleam@dynamic@decode:then(
_pipe@7,
fun(
Character_maximum_length
) ->
_pipe@8 = gleam@dynamic@decode:at(
[8],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_int/1}
)
),
gleam@dynamic@decode:then(
_pipe@8,
fun(
Numeric_precision
) ->
_pipe@9 = gleam@dynamic@decode:at(
[9],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_int/1}
)
),
gleam@dynamic@decode:then(
_pipe@9,
fun(
Numeric_scale
) ->
_pipe@10 = gleam@dynamic@decode:at(
[10],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_int/1}
)
),
gleam@dynamic@decode:then(
_pipe@10,
fun(
Datetime_precision
) ->
_pipe@11 = gleam@dynamic@decode:at(
[11],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
gleam@dynamic@decode:map(
_pipe@11,
fun(
Column_default
) ->
{column_row,
Schema_name,
Table_name,
Column_name,
Ordinal_position,
Is_nullable,
Data_type,
Udt_name,
Character_maximum_length,
Numeric_precision,
Numeric_scale,
Datetime_precision,
Column_default}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 349).
-spec index_row_decoder() -> gleam@dynamic@decode:decoder(index_row()).
index_row_decoder() ->
_pipe = gleam@dynamic@decode:at(
[0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe,
fun(Schema_name) ->
_pipe@1 = gleam@dynamic@decode:at(
[1],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@1,
fun(Table_name) ->
_pipe@2 = gleam@dynamic@decode:at(
[2],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@2,
fun(Index_name) ->
_pipe@3 = gleam@dynamic@decode:at(
[3],
{decoder,
fun gleam@dynamic@decode:decode_bool/1}
),
gleam@dynamic@decode:then(
_pipe@3,
fun(Is_unique) ->
_pipe@4 = gleam@dynamic@decode:at(
[4],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:map(
_pipe@4,
fun(Definition) ->
{index_row,
Schema_name,
Table_name,
Index_name,
Is_unique,
Definition}
end
)
end
)
end
)
end
)
end
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 404).
-spec compile_system_filter(binary(), boolean()) -> binary().
compile_system_filter(Qualifier, Include_system_schemas) ->
case Include_system_schemas of
true ->
<<""/utf8>>;
false ->
<<<<" AND "/utf8, Qualifier/binary>>/binary,
" NOT IN ('pg_catalog', 'information_schema')"/utf8>>
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 542).
-spec collect_constraint_rows(
list(constraint_row()),
binary(),
binary(),
binary(),
list(constraint_row())
) -> {list(constraint_row()), list(constraint_row())}.
collect_constraint_rows(Rows, Schema_name, Table_name, Constraint_name, Acc) ->
case Rows of
[] ->
{Acc, []};
[Row | Rest] ->
case ((erlang:element(2, Row) =:= Schema_name) andalso (erlang:element(
3,
Row
)
=:= Table_name))
andalso (erlang:element(4, Row) =:= Constraint_name) of
true ->
collect_constraint_rows(
Rest,
Schema_name,
Table_name,
Constraint_name,
[Row | Acc]
);
false ->
{Acc, Rows}
end
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 737).
-spec empty_table(
binary(),
binary(),
list(galchemy@schema@model:column_schema())
) -> galchemy@schema@model:table_schema().
empty_table(Schema_name, Table_name, Columns) ->
{table_schema, Schema_name, Table_name, Columns, none, [], [], []}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 715).
-spec upsert_table(
list(galchemy@schema@model:table_schema()),
binary(),
binary(),
fun((galchemy@schema@model:table_schema()) -> galchemy@schema@model:table_schema())
) -> list(galchemy@schema@model:table_schema()).
upsert_table(Tables, Schema_name, Table_name, Updater) ->
case Tables of
[] ->
[Updater(empty_table(Schema_name, Table_name, []))];
[Table_schema | Rest] ->
case (erlang:element(2, Table_schema) =:= Schema_name) andalso (erlang:element(
3,
Table_schema
)
=:= Table_name) of
true ->
[Updater(Table_schema) | Rest];
false ->
[Table_schema |
upsert_table(Rest, Schema_name, Table_name, Updater)]
end
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 662).
-spec apply_index_rows(
list(galchemy@schema@model:table_schema()),
list(index_row())
) -> list(galchemy@schema@model:table_schema()).
apply_index_rows(Tables, Rows) ->
case Rows of
[] ->
Tables;
[Row | Rest] ->
Next_tables = upsert_table(
Tables,
erlang:element(2, Row),
erlang:element(3, Row),
fun(Table_schema) ->
{table_schema,
erlang:element(2, Table_schema),
erlang:element(3, Table_schema),
erlang:element(4, Table_schema),
erlang:element(5, Table_schema),
erlang:element(6, Table_schema),
erlang:element(7, Table_schema),
lists:append(
erlang:element(8, Table_schema),
[{index_schema,
erlang:element(4, Row),
erlang:element(5, Row),
erlang:element(6, Row)}]
)}
end
),
apply_index_rows(Next_tables, Rest)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 783).
-spec infer_array_item_type(binary()) -> galchemy@schema@model:column_type().
infer_array_item_type(Udt_name) ->
case Udt_name of
<<"_int2"/utf8>> ->
small_int_type;
<<"_int4"/utf8>> ->
integer_type;
<<"_int8"/utf8>> ->
big_int_type;
<<"_bool"/utf8>> ->
boolean_type;
<<"_text"/utf8>> ->
text_type;
<<"_varchar"/utf8>> ->
{var_char_type, none};
<<"_timestamp"/utf8>> ->
{timestamp_type, false};
<<"_timestamptz"/utf8>> ->
{timestamp_type, true};
<<"_time"/utf8>> ->
{time_type, false};
<<"_timetz"/utf8>> ->
{time_type, true};
<<"_date"/utf8>> ->
date_type;
<<"_float4"/utf8>> ->
real_type;
<<"_float8"/utf8>> ->
double_precision_type;
<<"_numeric"/utf8>> ->
{numeric_type, none, none};
<<"_json"/utf8>> ->
json_type;
<<"_jsonb"/utf8>> ->
jsonb_type;
<<"_uuid"/utf8>> ->
uuid_type;
<<"_bytea"/utf8>> ->
bytea_type;
_ ->
{custom_type, Udt_name}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 753).
-spec infer_column_type(column_row()) -> galchemy@schema@model:column_type().
infer_column_type(Row) ->
case erlang:element(7, Row) of
<<"smallint"/utf8>> ->
small_int_type;
<<"integer"/utf8>> ->
integer_type;
<<"bigint"/utf8>> ->
big_int_type;
<<"boolean"/utf8>> ->
boolean_type;
<<"text"/utf8>> ->
text_type;
<<"character varying"/utf8>> ->
{var_char_type, erlang:element(9, Row)};
<<"timestamp without time zone"/utf8>> ->
{timestamp_type, false};
<<"timestamp with time zone"/utf8>> ->
{timestamp_type, true};
<<"time without time zone"/utf8>> ->
{time_type, false};
<<"time with time zone"/utf8>> ->
{time_type, true};
<<"date"/utf8>> ->
date_type;
<<"real"/utf8>> ->
real_type;
<<"double precision"/utf8>> ->
double_precision_type;
<<"numeric"/utf8>> ->
{numeric_type, erlang:element(10, Row), erlang:element(11, Row)};
<<"json"/utf8>> ->
json_type;
<<"jsonb"/utf8>> ->
jsonb_type;
<<"uuid"/utf8>> ->
uuid_type;
<<"bytea"/utf8>> ->
bytea_type;
<<"ARRAY"/utf8>> ->
{array_type, infer_array_item_type(erlang:element(8, Row))};
_ ->
{custom_type, erlang:element(8, Row)}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 807).
-spec constraint_kind_from_string(binary()) -> constraint_kind().
constraint_kind_from_string(Value) ->
case Value of
<<"PRIMARY KEY"/utf8>> ->
primary_key_constraint;
<<"UNIQUE"/utf8>> ->
unique_constraint;
<<"FOREIGN KEY"/utf8>> ->
foreign_key_constraint;
_ ->
Message = <<"Unsupported constraint kind: "/utf8, Value/binary>>,
erlang:error(#{gleam_error => panic,
message => Message,
file => <<?FILEPATH/utf8>>,
module => <<"galchemy/schema/introspection/postgres"/utf8>>,
function => <<"constraint_kind_from_string"/utf8>>,
line => 814})
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 308).
-spec constraint_row_decoder() -> gleam@dynamic@decode:decoder(constraint_row()).
constraint_row_decoder() ->
_pipe = gleam@dynamic@decode:at(
[0],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe,
fun(Schema_name) ->
_pipe@1 = gleam@dynamic@decode:at(
[1],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@1,
fun(Table_name) ->
_pipe@2 = gleam@dynamic@decode:at(
[2],
{decoder, fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@2,
fun(Constraint_name) ->
_pipe@3 = gleam@dynamic@decode:at(
[3],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@3,
fun(Kind_name) ->
_pipe@4 = gleam@dynamic@decode:at(
[4],
{decoder,
fun gleam@dynamic@decode:decode_string/1}
),
gleam@dynamic@decode:then(
_pipe@4,
fun(Column_name) ->
_pipe@5 = gleam@dynamic@decode:at(
[5],
{decoder,
fun gleam@dynamic@decode:decode_int/1}
),
gleam@dynamic@decode:then(
_pipe@5,
fun(Ordinal_position) ->
_pipe@6 = gleam@dynamic@decode:at(
[6],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
gleam@dynamic@decode:then(
_pipe@6,
fun(Referenced_schema) ->
_pipe@7 = gleam@dynamic@decode:at(
[7],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
gleam@dynamic@decode:then(
_pipe@7,
fun(
Referenced_table
) ->
_pipe@8 = gleam@dynamic@decode:at(
[8],
gleam@dynamic@decode:optional(
{decoder,
fun gleam@dynamic@decode:decode_string/1}
)
),
gleam@dynamic@decode:map(
_pipe@8,
fun(
Referenced_column
) ->
{constraint_row,
Schema_name,
Table_name,
Constraint_name,
constraint_kind_from_string(
Kind_name
),
Column_name,
Ordinal_position,
Referenced_schema,
Referenced_table,
Referenced_column}
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
)
end
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 819).
-spec option_or_panic(gleam@option:option(NGF), binary()) -> NGF.
option_or_panic(Value, Message) ->
case Value of
{some, Inner} ->
Inner;
none ->
erlang:error(#{gleam_error => panic,
message => Message,
file => <<?FILEPATH/utf8>>,
module => <<"galchemy/schema/introspection/postgres"/utf8>>,
function => <<"option_or_panic"/utf8>>,
line => 822})
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 833).
-spec join_strings_loop(list(binary()), binary(), binary()) -> binary().
join_strings_loop(Parts, Acc, Sep) ->
case Parts of
[] ->
Acc;
[Part | Rest] ->
join_strings_loop(
Rest,
<<<<Acc/binary, Sep/binary>>/binary, Part/binary>>,
Sep
)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 826).
-spec join_strings(list(binary()), binary()) -> binary().
join_strings(Parts, Sep) ->
case Parts of
[] ->
<<""/utf8>>;
[First | Rest] ->
join_strings_loop(Rest, First, Sep)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 844).
-spec reverse_loop(list(NGM), list(NGM)) -> list(NGM).
reverse_loop(Items, Acc) ->
case Items of
[] ->
Acc;
[Item | Rest] ->
reverse_loop(Rest, [Item | Acc])
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 840).
-spec reverse(list(NGJ)) -> list(NGJ).
reverse(Items) ->
reverse_loop(Items, []).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 437).
-spec schema_placeholders(list(binary()), integer(), list(binary())) -> list(binary()).
schema_placeholders(Schemas, Next_index, Acc) ->
case Schemas of
[] ->
reverse(Acc);
[_ | Rest] ->
schema_placeholders(
Rest,
Next_index + 1,
[<<"$"/utf8, (erlang:integer_to_binary(Next_index))/binary>> |
Acc]
)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 415).
-spec compile_schema_filter(binary(), list(binary())) -> {binary(),
list(galchemy@ast@expression:sql_value())}.
compile_schema_filter(Qualifier, Schemas) ->
case Schemas of
[] ->
{<<""/utf8>>, []};
_ ->
Placeholders = schema_placeholders(Schemas, 1, []),
Params = gleam@list:map(
Schemas,
fun(Field@0) -> {text, Field@0} end
),
{<<<<<<<<" AND "/utf8, Qualifier/binary>>/binary, " IN ("/utf8>>/binary,
(join_strings(Placeholders, <<", "/utf8>>))/binary>>/binary,
")"/utf8>>,
Params}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 89).
-spec compile_columns_query(introspection_options()) -> galchemy@sql@compiler:compiled_query().
compile_columns_query(Options) ->
{introspection_options, Schemas, Include_system_schemas} = Options,
Base_sql = <<<<<<<<<<<<<<<<"SELECT c.table_schema, c.table_name, c.column_name, c.ordinal_position, "/utf8,
"(c.is_nullable = 'YES') AS is_nullable, "/utf8>>/binary,
"c.data_type, c.udt_name, c.character_maximum_length, "/utf8>>/binary,
"c.numeric_precision, c.numeric_scale, c.datetime_precision, c.column_default "/utf8>>/binary,
"FROM information_schema.columns AS c "/utf8>>/binary,
"INNER JOIN information_schema.tables AS t "/utf8>>/binary,
"ON t.table_schema = c.table_schema "/utf8>>/binary,
"AND t.table_name = c.table_name "/utf8>>/binary,
"WHERE t.table_type = 'BASE TABLE'"/utf8>>,
System_filter_sql = compile_system_filter(
<<"c.table_schema"/utf8>>,
Include_system_schemas
),
{Schema_filter_sql, Params} = compile_schema_filter(
<<"c.table_schema"/utf8>>,
Schemas
),
{compiled_query,
<<<<<<Base_sql/binary, System_filter_sql/binary>>/binary,
Schema_filter_sql/binary>>/binary,
" ORDER BY c.table_schema, c.table_name, c.ordinal_position"/utf8>>,
Params}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 85).
-spec compile_query(introspection_options()) -> galchemy@sql@compiler:compiled_query().
compile_query(Options) ->
compile_columns_query(Options).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 122).
-spec compile_constraints_query(introspection_options()) -> galchemy@sql@compiler:compiled_query().
compile_constraints_query(Options) ->
{introspection_options, Schemas, Include_system_schemas} = Options,
Base_sql = <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"SELECT tc.table_schema, tc.table_name, tc.constraint_name, tc.constraint_type, "/utf8,
"kcu.column_name, kcu.ordinal_position, "/utf8>>/binary,
"ccu.table_schema AS referenced_schema, "/utf8>>/binary,
"ccu.table_name AS referenced_table, "/utf8>>/binary,
"ccu.column_name AS referenced_column "/utf8>>/binary,
"FROM information_schema.table_constraints AS tc "/utf8>>/binary,
"INNER JOIN information_schema.key_column_usage AS kcu "/utf8>>/binary,
"ON tc.constraint_schema = kcu.constraint_schema "/utf8>>/binary,
"AND tc.constraint_name = kcu.constraint_name "/utf8>>/binary,
"AND tc.table_schema = kcu.table_schema "/utf8>>/binary,
"AND tc.table_name = kcu.table_name "/utf8>>/binary,
"LEFT JOIN information_schema.referential_constraints AS rc "/utf8>>/binary,
"ON tc.constraint_schema = rc.constraint_schema "/utf8>>/binary,
"AND tc.constraint_name = rc.constraint_name "/utf8>>/binary,
"LEFT JOIN information_schema.key_column_usage AS ccu "/utf8>>/binary,
"ON rc.unique_constraint_schema = ccu.constraint_schema "/utf8>>/binary,
"AND rc.unique_constraint_name = ccu.constraint_name "/utf8>>/binary,
"AND kcu.position_in_unique_constraint = ccu.ordinal_position "/utf8>>/binary,
"WHERE tc.constraint_type IN ('PRIMARY KEY', 'UNIQUE', 'FOREIGN KEY')"/utf8>>,
System_filter_sql = compile_system_filter(
<<"tc.table_schema"/utf8>>,
Include_system_schemas
),
{Schema_filter_sql, Params} = compile_schema_filter(
<<"tc.table_schema"/utf8>>,
Schemas
),
{compiled_query,
<<<<<<Base_sql/binary, System_filter_sql/binary>>/binary,
Schema_filter_sql/binary>>/binary,
" ORDER BY tc.table_schema, tc.table_name, tc.constraint_name, kcu.ordinal_position"/utf8>>,
Params}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 165).
-spec compile_indexes_query(introspection_options()) -> galchemy@sql@compiler:compiled_query().
compile_indexes_query(Options) ->
{introspection_options, Schemas, Include_system_schemas} = Options,
Base_sql = <<<<<<<<<<<<<<"SELECT ns.nspname AS table_schema, tbl.relname AS table_name, "/utf8,
"idx.relname AS index_name, ind.indisunique AS is_unique, "/utf8>>/binary,
"pg_get_indexdef(ind.indexrelid) AS index_definition "/utf8>>/binary,
"FROM pg_index AS ind "/utf8>>/binary,
"INNER JOIN pg_class AS tbl ON tbl.oid = ind.indrelid "/utf8>>/binary,
"INNER JOIN pg_namespace AS ns ON ns.oid = tbl.relnamespace "/utf8>>/binary,
"INNER JOIN pg_class AS idx ON idx.oid = ind.indexrelid "/utf8>>/binary,
"WHERE tbl.relkind = 'r' AND NOT ind.indisprimary"/utf8>>,
System_filter_sql = compile_system_filter(
<<"ns.nspname"/utf8>>,
Include_system_schemas
),
{Schema_filter_sql, Params} = compile_schema_filter(
<<"ns.nspname"/utf8>>,
Schemas
),
{compiled_query,
<<<<<<Base_sql/binary, System_filter_sql/binary>>/binary,
Schema_filter_sql/binary>>/binary,
" ORDER BY ns.nspname, tbl.relname, idx.relname"/utf8>>,
Params}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 201).
-spec to_columns_query(introspection_options()) -> pog:'query'(column_row()).
to_columns_query(Options) ->
pog:returning(
galchemy@sql@postgres:to_query_from_compiled(
compile_columns_query(Options)
),
column_row_decoder()
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 197).
-spec to_query(introspection_options()) -> pog:'query'(column_row()).
to_query(Options) ->
to_columns_query(Options).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 208).
-spec to_constraints_query(introspection_options()) -> pog:'query'(constraint_row()).
to_constraints_query(Options) ->
pog:returning(
galchemy@sql@postgres:to_query_from_compiled(
compile_constraints_query(Options)
),
constraint_row_decoder()
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 217).
-spec to_indexes_query(introspection_options()) -> pog:'query'(index_row()).
to_indexes_query(Options) ->
pog:returning(
galchemy@sql@postgres:to_query_from_compiled(
compile_indexes_query(Options)
),
index_row_decoder()
).
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 374).
-spec execute_columns_query(pog:connection(), introspection_options()) -> {ok,
list(column_row())} |
{error, introspection_error()}.
execute_columns_query(Connection, Options) ->
case pog:execute(to_columns_query(Options), Connection) of
{ok, {returned, _, Rows}} ->
{ok, Rows};
{error, Error} ->
{error, {columns_query_error, Error}}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 384).
-spec execute_constraints_query(pog:connection(), introspection_options()) -> {ok,
list(constraint_row())} |
{error, introspection_error()}.
execute_constraints_query(Connection, Options) ->
case pog:execute(to_constraints_query(Options), Connection) of
{ok, {returned, _, Rows}} ->
{ok, Rows};
{error, Error} ->
{error, {constraints_query_error, Error}}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 394).
-spec execute_indexes_query(pog:connection(), introspection_options()) -> {ok,
list(index_row())} |
{error, introspection_error()}.
execute_indexes_query(Connection, Options) ->
case pog:execute(to_indexes_query(Options), Connection) of
{ok, {returned, _, Rows}} ->
{ok, Rows};
{error, Error} ->
{error, {indexes_query_error, Error}}
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 498).
-spec column_rows_to_columns(
list(column_row()),
list(galchemy@schema@model:column_schema())
) -> list(galchemy@schema@model:column_schema()).
column_rows_to_columns(Rows, Acc) ->
case Rows of
[] ->
reverse(Acc);
[Row | Rest] ->
column_rows_to_columns(
Rest,
[{column_schema,
erlang:element(4, Row),
infer_column_type(Row),
erlang:element(6, Row),
erlang:element(13, Row),
erlang:element(5, Row)} |
Acc]
)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 466).
-spec collect_table_rows(
list(column_row()),
binary(),
binary(),
list(column_row())
) -> {galchemy@schema@model:table_schema(), list(column_row())}.
collect_table_rows(Rows, Schema_name, Table_name, Acc) ->
case Rows of
[] ->
{empty_table(
Schema_name,
Table_name,
column_rows_to_columns(reverse(Acc), [])
),
[]};
[Row | Rest] ->
case (erlang:element(2, Row) =:= Schema_name) andalso (erlang:element(
3,
Row
)
=:= Table_name) of
true ->
collect_table_rows(
Rest,
Schema_name,
Table_name,
[Row | Acc]
);
false ->
{empty_table(
Schema_name,
Table_name,
column_rows_to_columns(reverse(Acc), [])
),
Rows}
end
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 452).
-spec column_rows_to_tables(
list(column_row()),
list(galchemy@schema@model:table_schema())
) -> list(galchemy@schema@model:table_schema()).
column_rows_to_tables(Rows, Acc) ->
case Rows of
[] ->
reverse(Acc);
[First | Rest] ->
{Table_schema, Remaining_rows} = collect_table_rows(
Rest,
erlang:element(2, First),
erlang:element(3, First),
[First]
),
column_rows_to_tables(Remaining_rows, [Table_schema | Acc])
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 688).
-spec constraint_columns(list(constraint_row()), list(binary())) -> list(binary()).
constraint_columns(Rows, Acc) ->
case Rows of
[] ->
reverse(Acc);
[Row | Rest] ->
constraint_columns(Rest, [erlang:element(6, Row) | Acc])
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 589).
-spec add_primary_key(list(constraint_row())) -> fun((galchemy@schema@model:table_schema()) -> galchemy@schema@model:table_schema()).
add_primary_key(Rows) ->
fun(Table_schema) -> case Rows of
[] ->
Table_schema;
[First | _] ->
{table_schema,
erlang:element(2, Table_schema),
erlang:element(3, Table_schema),
erlang:element(4, Table_schema),
{some,
{primary_key,
erlang:element(4, First),
constraint_columns(Rows, [])}},
erlang:element(6, Table_schema),
erlang:element(7, Table_schema),
erlang:element(8, Table_schema)}
end end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 607).
-spec add_unique_constraint(list(constraint_row())) -> fun((galchemy@schema@model:table_schema()) -> galchemy@schema@model:table_schema()).
add_unique_constraint(Rows) ->
fun(Table_schema) -> case Rows of
[] ->
Table_schema;
[First | _] ->
{table_schema,
erlang:element(2, Table_schema),
erlang:element(3, Table_schema),
erlang:element(4, Table_schema),
erlang:element(5, Table_schema),
lists:append(
erlang:element(6, Table_schema),
[{unique_constraint,
erlang:element(4, First),
constraint_columns(Rows, [])}]
),
erlang:element(7, Table_schema),
erlang:element(8, Table_schema)}
end end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 698).
-spec foreign_key_columns(list(constraint_row()), list(binary())) -> list(binary()).
foreign_key_columns(Rows, Acc) ->
case Rows of
[] ->
reverse(Acc);
[Row | Rest] ->
Referenced_column = option_or_panic(
erlang:element(10, Row),
<<"Foreign key referenced column is missing"/utf8>>
),
foreign_key_columns(Rest, [Referenced_column | Acc])
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 627).
-spec add_foreign_key(list(constraint_row())) -> fun((galchemy@schema@model:table_schema()) -> galchemy@schema@model:table_schema()).
add_foreign_key(Rows) ->
fun(Table_schema) -> case Rows of
[] ->
Table_schema;
[First | _] ->
Referenced_schema = option_or_panic(
erlang:element(8, First),
<<"Foreign key referenced schema is missing"/utf8>>
),
Referenced_table = option_or_panic(
erlang:element(9, First),
<<"Foreign key referenced table is missing"/utf8>>
),
{table_schema,
erlang:element(2, Table_schema),
erlang:element(3, Table_schema),
erlang:element(4, Table_schema),
erlang:element(5, Table_schema),
erlang:element(6, Table_schema),
lists:append(
erlang:element(7, Table_schema),
[{foreign_key,
erlang:element(4, First),
constraint_columns(Rows, []),
Referenced_schema,
Referenced_table,
foreign_key_columns(Rows, [])}]
),
erlang:element(8, Table_schema)}
end end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 571).
-spec apply_constraint_group(
list(galchemy@schema@model:table_schema()),
list(constraint_row())
) -> list(galchemy@schema@model:table_schema()).
apply_constraint_group(Tables, Rows) ->
case Rows of
[] ->
Tables;
[First | _] ->
Updater = case erlang:element(5, First) of
primary_key_constraint ->
add_primary_key(Rows);
unique_constraint ->
add_unique_constraint(Rows);
foreign_key_constraint ->
add_foreign_key(Rows)
end,
upsert_table(
Tables,
erlang:element(2, First),
erlang:element(3, First),
Updater
)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 518).
-spec apply_constraint_rows(
list(galchemy@schema@model:table_schema()),
list(constraint_row())
) -> list(galchemy@schema@model:table_schema()).
apply_constraint_rows(Tables, Rows) ->
case Rows of
[] ->
Tables;
[First | Rest] ->
{Same_constraint_rows, Remaining_rows} = collect_constraint_rows(
Rest,
erlang:element(2, First),
erlang:element(3, First),
erlang:element(4, First),
[First]
),
Next_tables = apply_constraint_group(
Tables,
reverse(Same_constraint_rows)
),
apply_constraint_rows(Next_tables, Remaining_rows)
end.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 244).
-spec rows_to_snapshot(
list(column_row()),
list(constraint_row()),
list(index_row())
) -> galchemy@schema@model:schema_snapshot().
rows_to_snapshot(Columns, Constraints, Indexes) ->
Base_tables = column_rows_to_tables(Columns, []),
Tables_with_constraints = apply_constraint_rows(Base_tables, Constraints),
Tables_with_indexes = apply_index_rows(Tables_with_constraints, Indexes),
{schema_snapshot, Tables_with_indexes}.
-file("src\\galchemy\\schema\\introspection\\postgres.gleam", 224).
-spec introspect(pog:connection(), introspection_options()) -> {ok,
galchemy@schema@model:schema_snapshot()} |
{error, introspection_error()}.
introspect(Connection, Options) ->
case execute_columns_query(Connection, Options) of
{ok, Columns} ->
case execute_constraints_query(Connection, Options) of
{ok, Constraints} ->
case execute_indexes_query(Connection, Options) of
{ok, Indexes} ->
{ok,
rows_to_snapshot(Columns, Constraints, Indexes)};
{error, Error} ->
{error, Error}
end;
{error, Error@1} ->
{error, Error@1}
end;
{error, Error@2} ->
{error, Error@2}
end.