Packages

SQL query builder core for Gleam

Current section

Files

Jump to
galchemy src galchemy@session@loading.erl
Raw

src/galchemy@session@loading.erl

-module(galchemy@session@loading).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src\\galchemy\\session\\loading.gleam").
-export([eager_join/4, apply_eager/5, lazy_query/4]).
-export_type([load_error/0, eager_load/0, lazy_load/0]).
-type load_error() :: {unknown_table, galchemy@schema@relation:table_ref()} |
{unknown_relation, galchemy@schema@relation:table_ref(), binary()} |
{empty_parent_identities, galchemy@schema@relation:table_ref(), binary()} |
{missing_identity_field,
galchemy@schema@relation:table_ref(),
binary(),
binary()}.
-type eager_load() :: {eager_load,
galchemy@schema@relation:relation(),
galchemy@ast@schema:table(),
galchemy@ast@expression:join()}.
-type lazy_load() :: {lazy_load,
galchemy@schema@relation:relation(),
galchemy@ast@query:'query'()}.
-file("src\\galchemy\\session\\loading.gleam", 158).
-spec find_relation_in(list(galchemy@schema@relation:relation()), binary()) -> gleam@option:option(galchemy@schema@relation:relation()).
find_relation_in(Relations, Relation_name) ->
case Relations of
[] ->
none;
[Next_relation | Rest] ->
case erlang:element(2, Next_relation) =:= Relation_name of
true ->
{some, Next_relation};
false ->
find_relation_in(Rest, Relation_name)
end
end.
-file("src\\galchemy\\session\\loading.gleam", 142).
-spec find_relation(
galchemy@schema@model:schema_snapshot(),
galchemy@schema@relation:table_ref(),
binary()
) -> {ok, galchemy@schema@relation:relation()} | {error, load_error()}.
find_relation(Snapshot, Table, Relation_name) ->
case galchemy@schema@relation:for_table(
Snapshot,
erlang:element(2, Table),
erlang:element(3, Table)
) of
none ->
{error, {unknown_table, Table}};
{some, Table_relations} ->
case find_relation_in(
erlang:element(3, Table_relations),
Relation_name
) of
{some, Next_relation} ->
{ok, Next_relation};
none ->
{error, {unknown_relation, Table, Relation_name}}
end
end.
-file("src\\galchemy\\session\\loading.gleam", 214).
-spec join_pair_predicate(
galchemy@ast@schema:table(),
galchemy@ast@schema:table(),
galchemy@schema@relation:column_pair()
) -> galchemy@ast@expression:predicate().
join_pair_predicate(Source_table, Related_table, Pair) ->
{comparison,
{column_expr, {column_meta, Source_table, erlang:element(2, Pair)}},
eq,
{column_expr, {column_meta, Related_table, erlang:element(3, Pair)}}}.
-file("src\\galchemy\\session\\loading.gleam", 193).
-spec join_predicate_rest(
galchemy@ast@schema:table(),
galchemy@ast@schema:table(),
list(galchemy@schema@relation:column_pair()),
galchemy@ast@expression:predicate()
) -> galchemy@ast@expression:predicate().
join_predicate_rest(Source_table, Related_table, Pairs, Acc) ->
case Pairs of
[] ->
Acc;
[Pair | Rest] ->
join_predicate_rest(
Source_table,
Related_table,
Rest,
{'and',
Acc,
join_pair_predicate(Source_table, Related_table, Pair)}
)
end.
-file("src\\galchemy\\session\\loading.gleam", 173).
-spec join_predicate(
galchemy@ast@schema:table(),
galchemy@ast@schema:table(),
list(galchemy@schema@relation:column_pair())
) -> galchemy@ast@expression:predicate().
join_predicate(Source_table, Related_table, Column_pairs) ->
case Column_pairs of
[] ->
{comparison,
{value_expr, {bool, true}},
eq,
{value_expr, {bool, true}}};
[First | Rest] ->
Initial = join_pair_predicate(Source_table, Related_table, First),
join_predicate_rest(Source_table, Related_table, Rest, Initial)
end.
-file("src\\galchemy\\session\\loading.gleam", 402).
-spec find_field_value(
list(galchemy@session@unit_of_work:field_value()),
binary()
) -> gleam@option:option(galchemy@ast@expression:sql_value()).
find_field_value(Fields, Column_name) ->
case Fields of
[] ->
none;
[Field_value | Rest] ->
case erlang:element(2, Field_value) =:= Column_name of
true ->
{some, erlang:element(3, Field_value)};
false ->
find_field_value(Rest, Column_name)
end
end.
-file("src\\galchemy\\session\\loading.gleam", 385).
-spec identity_value(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@session@unit_of_work:identity(),
binary()
) -> {ok, galchemy@ast@expression:sql_value()} | {error, load_error()}.
identity_value(Source_table, Relation_name, Next_identity, Column_name) ->
case find_field_value(erlang:element(2, Next_identity), Column_name) of
{some, Value} ->
{ok, Value};
none ->
{error,
{missing_identity_field,
Source_table,
Relation_name,
Column_name}}
end.
-file("src\\galchemy\\session\\loading.gleam", 417).
-spec relation_ref_from_table(galchemy@ast@schema:table()) -> galchemy@schema@relation:table_ref().
relation_ref_from_table(Table) ->
galchemy@schema@relation:table_ref(case erlang:element(2, Table) of
{some, Schema_name} ->
Schema_name;
none ->
<<"public"/utf8>>
end, erlang:element(3, Table)).
-file("src\\galchemy\\session\\loading.gleam", 427).
-spec result_try(
{ok, JCN} | {error, JCO},
fun((JCN) -> {ok, JCR} | {error, JCO})
) -> {ok, JCR} | {error, JCO}.
result_try(Value, Next) ->
case Value of
{ok, Inner} ->
Next(Inner);
{error, Error} ->
{error, Error}
end.
-file("src\\galchemy\\session\\loading.gleam", 33).
-spec eager_join(
galchemy@schema@model:schema_snapshot(),
galchemy@ast@schema:table(),
binary(),
gleam@option:option(binary())
) -> {ok, eager_load()} | {error, load_error()}.
eager_join(Snapshot, Source_table, Relation_name, Alias) ->
Source_ref = relation_ref_from_table(Source_table),
result_try(
find_relation(Snapshot, Source_ref, Relation_name),
fun(Next_relation) ->
Related_table = {table,
{some, erlang:element(2, erlang:element(5, Next_relation))},
erlang:element(3, erlang:element(5, Next_relation)),
Alias},
{ok,
{eager_load,
Next_relation,
Related_table,
{join,
left_join,
{table_source, Related_table},
join_predicate(
Source_table,
Related_table,
erlang:element(6, Next_relation)
)}}}
end
).
-file("src\\galchemy\\session\\loading.gleam", 67).
-spec apply_eager(
galchemy@ast@expression:select_query(),
galchemy@schema@model:schema_snapshot(),
galchemy@ast@schema:table(),
binary(),
gleam@option:option(binary())
) -> {ok, galchemy@ast@expression:select_query()} | {error, load_error()}.
apply_eager(Select_query, Snapshot, Source_table, Relation_name, Alias) ->
result_try(
eager_join(Snapshot, Source_table, Relation_name, Alias),
fun(Eager) ->
{ok,
{select_query,
erlang:element(2, Select_query),
erlang:element(3, Select_query),
erlang:element(4, Select_query),
lists:append(
erlang:element(5, Select_query),
[erlang:element(4, Eager)]
),
erlang:element(6, Select_query),
erlang:element(7, Select_query),
erlang:element(8, Select_query),
erlang:element(9, Select_query),
erlang:element(10, Select_query),
erlang:element(11, Select_query),
erlang:element(12, Select_query),
erlang:element(13, Select_query)}}
end
).
-file("src\\galchemy\\session\\loading.gleam", 354).
-spec identity_pair_predicate(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@schema@relation:table_ref(),
galchemy@session@unit_of_work:identity(),
galchemy@schema@relation:column_pair()
) -> {ok, galchemy@ast@expression:predicate()} | {error, load_error()}.
identity_pair_predicate(
Source_table,
Relation_name,
Related_table,
Next_identity,
Pair
) ->
result_try(
identity_value(
Source_table,
Relation_name,
Next_identity,
erlang:element(2, Pair)
),
fun(Value) ->
Related_ast_table = {table,
{some, erlang:element(2, Related_table)},
erlang:element(3, Related_table),
none},
{ok,
{comparison,
{column_expr,
{column_meta,
Related_ast_table,
erlang:element(3, Pair)}},
eq,
{value_expr, Value}}}
end
).
-file("src\\galchemy\\session\\loading.gleam", 323).
-spec identity_predicate_rest(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@schema@relation:table_ref(),
galchemy@session@unit_of_work:identity(),
list(galchemy@schema@relation:column_pair()),
galchemy@ast@expression:predicate()
) -> {ok, galchemy@ast@expression:predicate()} | {error, load_error()}.
identity_predicate_rest(
Source_table,
Relation_name,
Related_table,
Next_identity,
Pairs,
Acc
) ->
case Pairs of
[] ->
{ok, Acc};
[Pair | Rest] ->
result_try(
identity_pair_predicate(
Source_table,
Relation_name,
Related_table,
Next_identity,
Pair
),
fun(Next_predicate) ->
identity_predicate_rest(
Source_table,
Relation_name,
Related_table,
Next_identity,
Rest,
{'and', Acc, Next_predicate}
)
end
)
end.
-file("src\\galchemy\\session\\loading.gleam", 290).
-spec identity_predicate(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@schema@relation:relation(),
galchemy@session@unit_of_work:identity()
) -> {ok, galchemy@ast@expression:predicate()} | {error, load_error()}.
identity_predicate(Source_table, Relation_name, Next_relation, Next_identity) ->
case erlang:element(6, Next_relation) of
[] ->
{error, {empty_parent_identities, Source_table, Relation_name}};
[First | Rest] ->
result_try(
identity_pair_predicate(
Source_table,
Relation_name,
erlang:element(5, Next_relation),
Next_identity,
First
),
fun(Initial) ->
identity_predicate_rest(
Source_table,
Relation_name,
erlang:element(5, Next_relation),
Next_identity,
Rest,
Initial
)
end
)
end.
-file("src\\galchemy\\session\\loading.gleam", 262).
-spec lazy_predicate_rest(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@schema@relation:relation(),
list(galchemy@session@unit_of_work:identity()),
galchemy@ast@expression:predicate()
) -> {ok, galchemy@ast@expression:predicate()} | {error, load_error()}.
lazy_predicate_rest(Source_table, Relation_name, Next_relation, Identities, Acc) ->
case Identities of
[] ->
{ok, Acc};
[Next_identity | Rest] ->
result_try(
identity_predicate(
Source_table,
Relation_name,
Next_relation,
Next_identity
),
fun(Next_predicate) ->
lazy_predicate_rest(
Source_table,
Relation_name,
Next_relation,
Rest,
{'or', Acc, Next_predicate}
)
end
)
end.
-file("src\\galchemy\\session\\loading.gleam", 232).
-spec lazy_predicate(
galchemy@schema@relation:table_ref(),
binary(),
galchemy@schema@relation:relation(),
list(galchemy@session@unit_of_work:identity())
) -> {ok, galchemy@ast@expression:predicate()} | {error, load_error()}.
lazy_predicate(Source_table, Relation_name, Next_relation, Identities) ->
case Identities of
[] ->
{error, {empty_parent_identities, Source_table, Relation_name}};
[First | Rest] ->
result_try(
identity_predicate(
Source_table,
Relation_name,
Next_relation,
First
),
fun(Initial) ->
lazy_predicate_rest(
Source_table,
Relation_name,
Next_relation,
Rest,
Initial
)
end
)
end.
-file("src\\galchemy\\session\\loading.gleam", 89).
-spec lazy_query(
galchemy@schema@model:schema_snapshot(),
galchemy@schema@relation:table_ref(),
binary(),
list(galchemy@session@unit_of_work:identity())
) -> {ok, lazy_load()} | {error, load_error()}.
lazy_query(Snapshot, Source_table, Relation_name, Identities) ->
case Identities of
[] ->
{error, {empty_parent_identities, Source_table, Relation_name}};
_ ->
result_try(
find_relation(Snapshot, Source_table, Relation_name),
fun(Next_relation) ->
result_try(
lazy_predicate(
Source_table,
Relation_name,
Next_relation,
Identities
),
fun(Where_) ->
Related_table = {table,
{some,
erlang:element(
2,
erlang:element(5, Next_relation)
)},
erlang:element(
3,
erlang:element(5, Next_relation)
),
none},
{ok,
{lazy_load,
Next_relation,
{select,
{select_query,
[],
[],
{some,
{table_source, Related_table}},
[],
{some, Where_},
[],
none,
[],
[],
none,
none,
false}}}}
end
)
end
)
end.