Current section
Files
Jump to
Current section
Files
src/sqlode@type_mapping.erl
-module(sqlode@type_mapping).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/sqlode/type_mapping.gleam").
-export([is_rich_type/1, strong_type_unwrap_fn/1, scalar_type_to_runtime_function/1, scalar_type_to_db_name/1, scalar_type_to_value_function/2, scalar_type_to_decoder/2, enum_to_string_fn/1, enum_from_string_fn/1, enum_default_fn/1, set_to_string_fn/1, set_from_string_fn/1, enum_type_name/1, enum_value_name/1, set_value_type_name/1, scalar_type_to_gleam_type/2]).
-export_type([scalar_type_info/0, type_resolution/0]).
-if(?OTP_RELEASE >= 27).
-define(MODULEDOC(Str), -moduledoc(Str)).
-define(DOC(Str), -doc(Str)).
-else.
-define(MODULEDOC(Str), -compile([])).
-define(DOC(Str), -compile([])).
-endif.
-type scalar_type_info() :: {scalar_type_info,
binary(),
gleam@option:option(binary()),
binary(),
binary(),
binary(),
binary(),
gleam@option:option(binary())}.
-type type_resolution() :: {leaf_type, scalar_type_info()} |
{enum_resolution, binary()} |
{set_resolution, binary()} |
{custom_resolution,
binary(),
gleam@option:option(binary()),
sqlode@model:scalar_type()} |
{array_resolution, sqlode@model:scalar_type()}.
-file("src/sqlode/type_mapping.gleam", 39).
-spec resolve_type(sqlode@model:scalar_type()) -> type_resolution().
resolve_type(Scalar_type) ->
case Scalar_type of
int_type ->
{leaf_type,
{scalar_type_info,
<<"Int"/utf8>>,
none,
<<"runtime.int"/utf8>>,
<<"int"/utf8>>,
<<"int"/utf8>>,
<<"decode.int"/utf8>>,
none}};
float_type ->
{leaf_type,
{scalar_type_info,
<<"Float"/utf8>>,
none,
<<"runtime.float"/utf8>>,
<<"float"/utf8>>,
<<"float"/utf8>>,
<<"decode.float"/utf8>>,
none}};
bool_type ->
{leaf_type,
{scalar_type_info,
<<"Bool"/utf8>>,
none,
<<"runtime.bool"/utf8>>,
<<"bool"/utf8>>,
<<"bool"/utf8>>,
<<"decode.bool"/utf8>>,
none}};
string_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
none,
<<"runtime.string"/utf8>>,
<<"string"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
none}};
bytes_type ->
{leaf_type,
{scalar_type_info,
<<"BitArray"/utf8>>,
none,
<<"runtime.bytes"/utf8>>,
<<"bytes"/utf8>>,
<<"bytea"/utf8>>,
<<"decode.bit_array"/utf8>>,
none}};
date_time_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlTimestamp"/utf8>>},
<<"runtime.string"/utf8>>,
<<"datetime"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_timestamp_to_string"/utf8>>}}};
date_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlDate"/utf8>>},
<<"runtime.string"/utf8>>,
<<"date"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_date_to_string"/utf8>>}}};
time_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlTime"/utf8>>},
<<"runtime.string"/utf8>>,
<<"time"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_time_to_string"/utf8>>}}};
uuid_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlUuid"/utf8>>},
<<"runtime.string"/utf8>>,
<<"uuid"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_uuid_to_string"/utf8>>}}};
json_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlJson"/utf8>>},
<<"runtime.string"/utf8>>,
<<"json"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_json_to_string"/utf8>>}}};
decimal_type ->
{leaf_type,
{scalar_type_info,
<<"String"/utf8>>,
{some, <<"SqlDecimal"/utf8>>},
<<"runtime.string"/utf8>>,
<<"decimal"/utf8>>,
<<"text"/utf8>>,
<<"decode.string"/utf8>>,
{some, <<"sql_decimal_to_string"/utf8>>}}};
{enum_type, Name} ->
{enum_resolution, Name};
{set_type, Name@1} ->
{set_resolution, Name@1};
{custom_type, Name@2, Module, Underlying} ->
{custom_resolution, Name@2, Module, Underlying};
{array_type, Element} ->
{array_resolution, Element}
end.
-file("src/sqlode/type_mapping.gleam", 180).
-spec is_rich_type(sqlode@model:scalar_type()) -> boolean().
is_rich_type(Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
gleam@option:is_some(erlang:element(3, Info));
{enum_resolution, _} ->
false;
{set_resolution, _} ->
false;
{custom_resolution, _, _, _} ->
false;
{array_resolution, _} ->
false
end.
-file("src/sqlode/type_mapping.gleam", 190).
-spec strong_type_unwrap_fn(sqlode@model:scalar_type()) -> gleam@option:option(binary()).
strong_type_unwrap_fn(Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
erlang:element(8, Info);
{enum_resolution, _} ->
none;
{set_resolution, _} ->
none;
{custom_resolution, _, _, _} ->
none;
{array_resolution, _} ->
none
end.
-file("src/sqlode/type_mapping.gleam", 200).
-spec scalar_type_to_runtime_function(sqlode@model:scalar_type()) -> binary().
scalar_type_to_runtime_function(Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
erlang:element(4, Info);
{enum_resolution, _} ->
<<"runtime.string"/utf8>>;
{set_resolution, _} ->
<<"runtime.string"/utf8>>;
{custom_resolution, _, _, Underlying} ->
scalar_type_to_runtime_function(Underlying);
{array_resolution, Element} ->
scalar_type_to_runtime_function(Element)
end.
-file("src/sqlode/type_mapping.gleam", 211).
-spec scalar_type_to_db_name(sqlode@model:scalar_type()) -> binary().
scalar_type_to_db_name(Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
erlang:element(5, Info);
{enum_resolution, Name} ->
Name;
{set_resolution, Name@1} ->
Name@1;
{custom_resolution, _, _, Underlying} ->
scalar_type_to_db_name(Underlying);
{array_resolution, Element} ->
<<(scalar_type_to_db_name(Element))/binary, "[]"/utf8>>
end.
-file("src/sqlode/type_mapping.gleam", 221).
-spec scalar_type_to_value_function(
sqlode@model:engine(),
sqlode@model:scalar_type()
) -> binary().
scalar_type_to_value_function(Engine, Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
case Scalar_type of
bytes_type ->
case Engine of
postgre_s_q_l ->
<<"bytea"/utf8>>;
s_q_lite ->
<<"blob"/utf8>>;
my_s_q_l ->
<<"blob"/utf8>>
end;
_ ->
erlang:element(6, Info)
end;
{enum_resolution, _} ->
<<"text"/utf8>>;
{set_resolution, _} ->
<<"text"/utf8>>;
{custom_resolution, _, _, Underlying} ->
scalar_type_to_value_function(Engine, Underlying);
{array_resolution, Element} ->
<<<<"array(pog."/utf8,
(scalar_type_to_value_function(Engine, Element))/binary>>/binary,
")"/utf8>>
end.
-file("src/sqlode/type_mapping.gleam", 244).
-spec scalar_type_to_decoder(sqlode@model:engine(), sqlode@model:scalar_type()) -> binary().
scalar_type_to_decoder(Engine, Scalar_type) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
case Scalar_type of
bool_type ->
case Engine of
s_q_lite ->
<<"decode.then(decode.int, fn(v) { decode.success(v != 0) })"/utf8>>;
my_s_q_l ->
<<"decode.then(decode.int, fn(v) { decode.success(v != 0) })"/utf8>>;
postgre_s_q_l ->
<<"decode.bool"/utf8>>
end;
_ ->
erlang:element(7, Info)
end;
{enum_resolution, _} ->
<<"decode.string"/utf8>>;
{set_resolution, _} ->
<<"decode.string"/utf8>>;
{custom_resolution, _, _, Underlying} ->
scalar_type_to_decoder(Engine, Underlying);
{array_resolution, Element} ->
<<<<"decode.list("/utf8,
(scalar_type_to_decoder(Engine, Element))/binary>>/binary,
")"/utf8>>
end.
-file("src/sqlode/type_mapping.gleam", 278).
-spec enum_to_string_fn(binary()) -> binary().
enum_to_string_fn(Name) ->
<<(string:lowercase(Name))/binary, "_to_string"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 282).
-spec enum_from_string_fn(binary()) -> binary().
enum_from_string_fn(Name) ->
<<(string:lowercase(Name))/binary, "_from_string"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 290).
?DOC(
" Name of the helper that returns the enum's first variant as a\n"
" `zero`-style fallback. Used by generated adapter / queries\n"
" decoders where `decode.failure(zero, msg)` needs a concrete value\n"
" of the target type.\n"
).
-spec enum_default_fn(binary()) -> binary().
enum_default_fn(Name) ->
<<(string:lowercase(Name))/binary, "_default"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 305).
-spec set_to_string_fn(binary()) -> binary().
set_to_string_fn(Name) ->
<<(string:lowercase(Name))/binary, "_set_to_string"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 309).
-spec set_from_string_fn(binary()) -> binary().
set_from_string_fn(Name) ->
<<(string:lowercase(Name))/binary, "_set_from_string"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 313).
-spec simple_pascal_case(binary()) -> binary().
simple_pascal_case(Input) ->
_pipe = Input,
_pipe@1 = gleam@string:split(_pipe, <<"_"/utf8>>),
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Word) -> case gleam_stdlib:string_pop_grapheme(Word) of
{ok, {First, Rest}} ->
<<(string:uppercase(First))/binary,
(string:lowercase(Rest))/binary>>;
{error, _} ->
Word
end end
),
gleam@string:join(_pipe@2, <<""/utf8>>).
-file("src/sqlode/type_mapping.gleam", 270).
-spec enum_type_name(binary()) -> binary().
enum_type_name(Name) ->
simple_pascal_case(Name).
-file("src/sqlode/type_mapping.gleam", 274).
-spec enum_value_name(binary()) -> binary().
enum_value_name(Value) ->
simple_pascal_case(Value).
-file("src/sqlode/type_mapping.gleam", 301).
?DOC(
" Gleam type name for a single value of a MySQL `SET` column. The\n"
" generated value type ends in `Value` to disambiguate it from the\n"
" containing list — `SET('red','green')` on a column called `tags`\n"
" surfaces as `List(TagsValue)` so callers can pattern-match on each\n"
" chosen flag without colliding with the SET column name.\n"
).
-spec set_value_type_name(binary()) -> binary().
set_value_type_name(Name) ->
<<(simple_pascal_case(Name))/binary, "Value"/utf8>>.
-file("src/sqlode/type_mapping.gleam", 161).
-spec scalar_type_to_gleam_type(
sqlode@model:scalar_type(),
sqlode@model:type_mapping()
) -> binary().
scalar_type_to_gleam_type(Scalar_type, Type_mapping) ->
case resolve_type(Scalar_type) of
{leaf_type, Info} ->
case {Type_mapping, erlang:element(3, Info)} of
{rich_mapping, {some, Rich}} ->
Rich;
{strong_mapping, {some, Rich}} ->
Rich;
{_, _} ->
erlang:element(2, Info)
end;
{enum_resolution, Name} ->
enum_type_name(Name);
{set_resolution, Name@1} ->
<<<<"List("/utf8, (set_value_type_name(Name@1))/binary>>/binary,
")"/utf8>>;
{custom_resolution, Name@2, _, _} ->
Name@2;
{array_resolution, Element} ->
<<<<"List("/utf8,
(scalar_type_to_gleam_type(Element, Type_mapping))/binary>>/binary,
")"/utf8>>
end.