Current section
Files
Jump to
Current section
Files
src/cquill@codegen@generator.erl
-module(cquill@codegen@generator).
-compile([no_auto_import, nowarn_unused_vars, nowarn_unused_function, nowarn_nomatch, inline]).
-define(FILEPATH, "src/cquill/codegen/generator.gleam").
-export([default_config/0, with_typed_columns/2, with_module_prefix/2, with_timestamp_fields/2, pascal_case/1, snake_case/1, generate_index_module/3, generate_schema_module/3, generate_enum_module/2, module_file_path/1, generate_typed_module/3, generate_typed_index_module/2, generate_all/3]).
-export_type([generator_config/0, generated_module/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 generator_config() :: {generator_config,
binary(),
boolean(),
list(binary()),
boolean(),
boolean(),
boolean()}.
-type generated_module() :: {generated_module, binary(), binary(), binary()}.
-file("src/cquill/codegen/generator.gleam", 51).
?DOC(" Create a default generator configuration\n").
-spec default_config() -> generator_config().
default_config() ->
{generator_config,
<<"db"/utf8>>,
true,
[<<"inserted_at"/utf8>>,
<<"updated_at"/utf8>>,
<<"created_at"/utf8>>,
<<"modified_at"/utf8>>],
true,
true,
true}.
-file("src/cquill/codegen/generator.gleam", 63).
?DOC(" Enable or disable typed column generation\n").
-spec with_typed_columns(generator_config(), boolean()) -> generator_config().
with_typed_columns(Config, Enabled) ->
{generator_config,
erlang:element(2, Config),
erlang:element(3, Config),
erlang:element(4, Config),
erlang:element(5, Config),
erlang:element(6, Config),
Enabled}.
-file("src/cquill/codegen/generator.gleam", 71).
?DOC(" Create a generator configuration with a custom module prefix\n").
-spec with_module_prefix(generator_config(), binary()) -> generator_config().
with_module_prefix(Config, Prefix) ->
{generator_config,
Prefix,
erlang:element(3, Config),
erlang:element(4, Config),
erlang:element(5, Config),
erlang:element(6, Config),
erlang:element(7, Config)}.
-file("src/cquill/codegen/generator.gleam", 79).
?DOC(" Set timestamp fields for a configuration\n").
-spec with_timestamp_fields(generator_config(), list(binary())) -> generator_config().
with_timestamp_fields(Config, Fields) ->
{generator_config,
erlang:element(2, Config),
erlang:element(3, Config),
Fields,
erlang:element(5, Config),
erlang:element(6, Config),
erlang:element(7, Config)}.
-file("src/cquill/codegen/generator.gleam", 186).
-spec generate_module_header(binary(), generator_config()) -> binary().
generate_module_header(Table_name, _) ->
<<<<<<<<<<<<"// "/utf8, Table_name/binary>>/binary,
".gleam (GENERATED)\n"/utf8>>/binary,
"//// Schema and types for "/utf8>>/binary,
Table_name/binary>>/binary,
" table\n"/utf8>>/binary,
"//// Generated by cquill - DO NOT EDIT\n"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 199).
-spec generate_enum_module_header(generator_config()) -> binary().
generate_enum_module_header(_) ->
<<<<"// enums.gleam (GENERATED)\n"/utf8, "//// Database enum types\n"/utf8>>/binary,
"//// Generated by cquill - DO NOT EDIT\n"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 205).
-spec generate_index_module_header(generator_config()) -> binary().
generate_index_module_header(_) ->
<<<<"// schema.gleam (GENERATED)\n"/utf8,
"//// Database schema definitions\n"/utf8>>/binary,
"//// Generated by cquill - DO NOT EDIT\n"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 215).
-spec generate_imports(
list(cquill@codegen@type_mapping:column_meta()),
generator_config()
) -> binary().
generate_imports(Columns, _) ->
Imports = cquill@codegen@type_mapping:collect_imports(Columns),
Standard_imports = [<<"import cquill/schema.{type Schema}"/utf8>>],
Type_imports = begin
_pipe = Imports,
gleam@list:filter_map(_pipe, fun(Imp) -> case Imp of
<<"gleam/option"/utf8>> ->
{ok, <<"import gleam/option.{type Option}"/utf8>>};
<<"birl"/utf8>> ->
{ok, <<"import birl.{type Time}"/utf8>>};
<<"uuid"/utf8>> ->
{ok, <<"import uuid.{type Uuid}"/utf8>>};
<<"decimal"/utf8>> ->
{ok, <<"import decimal.{type Decimal}"/utf8>>};
<<"gleam/json"/utf8>> ->
{ok, <<"import gleam/json.{type Json}"/utf8>>};
_ ->
{error, nil}
end end)
end,
All_imports = lists:append(Standard_imports, Type_imports),
gleam@string:join(All_imports, <<"\n"/utf8>>).
-file("src/cquill/codegen/generator.gleam", 240).
-spec generate_enum_imports() -> binary().
generate_enum_imports() ->
<<"import gleam/dynamic.{type Dynamic}\n"/utf8, "import gleam/result"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 420).
-spec generate_constraints(
cquill@codegen@type_mapping:column_meta(),
cquill@introspection:introspected_table()
) -> binary().
generate_constraints(Col, Table) ->
Mut_constraints = [],
Is_pk = gleam@list:contains(
erlang:element(4, Table),
erlang:element(6, Col)
),
Constraints = case Is_pk of
true ->
[<<"\"primary_key\""/utf8>> | Mut_constraints];
false ->
Mut_constraints
end,
Constraints@1 = case erlang:element(7, Col) of
false ->
[<<"\"not_null\""/utf8>> | Constraints];
true ->
Constraints
end,
Is_unique = gleam@list:any(
erlang:element(6, Table),
fun(U) -> erlang:element(3, U) =:= [erlang:element(6, Col)] end
),
Constraints@2 = case Is_unique of
true ->
[<<"\"unique\""/utf8>> | Constraints@1];
false ->
Constraints@1
end,
gleam@string:join(lists:reverse(Constraints@2), <<", "/utf8>>).
-file("src/cquill/codegen/generator.gleam", 721).
-spec render_type(cquill@codegen@type_mapping:gleam_type()) -> binary().
render_type(Gleam_type) ->
cquill@codegen@type_mapping:render_type(Gleam_type).
-file("src/cquill/codegen/generator.gleam", 288).
?DOC(" Generate the main record type (for SELECT results)\n").
-spec generate_record_type(
binary(),
list(cquill@codegen@type_mapping:column_meta())
) -> binary().
generate_record_type(Type_name, Columns) ->
Fields = begin
_pipe = Columns,
_pipe@1 = gleam@list:map(
_pipe,
fun(Col) ->
<<<<<<<<" "/utf8, (erlang:element(6, Col))/binary>>/binary,
": "/utf8>>/binary,
(render_type(erlang:element(2, Col)))/binary>>/binary,
","/utf8>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<"/// Full "/utf8, Type_name/binary>>/binary,
" record (for SELECT results)\n"/utf8>>/binary,
"pub type "/utf8>>/binary,
Type_name/binary>>/binary,
" {\n"/utf8>>/binary,
" "/utf8>>/binary,
Type_name/binary>>/binary,
"(\n"/utf8>>/binary,
Fields/binary>>/binary,
"\n )\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 311).
?DOC(" Generate the New type (for INSERT operations, excludes auto-generated)\n").
-spec generate_new_type(
binary(),
list(cquill@codegen@type_mapping:column_meta())
) -> binary().
generate_new_type(Type_name, Columns) ->
Insert_columns = begin
_pipe = Columns,
gleam@list:filter(_pipe, fun(Col) -> not erlang:element(3, Col) end)
end,
Fields = begin
_pipe@1 = Insert_columns,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Col@1) ->
<<<<<<<<" "/utf8, (erlang:element(6, Col@1))/binary>>/binary,
": "/utf8>>/binary,
(render_type(erlang:element(2, Col@1)))/binary>>/binary,
","/utf8>>
end
),
gleam@string:join(_pipe@2, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<"/// For INSERT operations (excludes auto-generated fields)\n"/utf8,
"pub type New"/utf8>>/binary,
Type_name/binary>>/binary,
" {\n"/utf8>>/binary,
" New"/utf8>>/binary,
Type_name/binary>>/binary,
"(\n"/utf8>>/binary,
Fields/binary>>/binary,
"\n )\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 336).
?DOC(" Generate the Changes type (for UPDATE operations, all fields optional)\n").
-spec generate_changes_type(
binary(),
list(cquill@codegen@type_mapping:column_meta())
) -> binary().
generate_changes_type(Type_name, Columns) ->
Update_columns = begin
_pipe = Columns,
gleam@list:filter(_pipe, fun(Col) -> not erlang:element(3, Col) end)
end,
Fields = begin
_pipe@1 = Update_columns,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Col@1) ->
Field_type = case erlang:element(2, Col@1) of
{gleam_option, Inner} ->
<<<<"Option(Option("/utf8, (render_type(Inner))/binary>>/binary,
"))"/utf8>>;
Other ->
<<<<"Option("/utf8, (render_type(Other))/binary>>/binary,
")"/utf8>>
end,
<<<<<<<<" "/utf8, (erlang:element(6, Col@1))/binary>>/binary,
": "/utf8>>/binary,
Field_type/binary>>/binary,
","/utf8>>
end
),
gleam@string:join(_pipe@2, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<"/// For UPDATE operations (all fields optional)\n"/utf8,
"pub type "/utf8>>/binary,
Type_name/binary>>/binary,
"Changes {\n"/utf8>>/binary,
" "/utf8>>/binary,
Type_name/binary>>/binary,
"Changes(\n"/utf8>>/binary,
Fields/binary>>/binary,
"\n )\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 725).
-spec render_field_type(cquill@codegen@type_mapping:gleam_type()) -> binary().
render_field_type(Gleam_type) ->
case Gleam_type of
gleam_int ->
<<"integer"/utf8>>;
gleam_float ->
<<"float"/utf8>>;
gleam_string ->
<<"string"/utf8>>;
gleam_bool ->
<<"boolean"/utf8>>;
gleam_bit_array ->
<<"binary"/utf8>>;
gleam_time ->
<<"timestamp"/utf8>>;
gleam_date ->
<<"date"/utf8>>;
gleam_time_of_day ->
<<"time"/utf8>>;
gleam_decimal ->
<<"decimal"/utf8>>;
gleam_uuid ->
<<"uuid"/utf8>>;
gleam_json ->
<<"json"/utf8>>;
{gleam_list, Element} ->
<<"array:"/utf8, (render_field_type(Element))/binary>>;
{gleam_option, Inner} ->
<<"optional:"/utf8, (render_field_type(Inner))/binary>>;
{gleam_custom, _, Type_name} ->
<<"custom:"/utf8, Type_name/binary>>
end.
-file("src/cquill/codegen/generator.gleam", 405).
-spec generate_field_definition(
cquill@codegen@type_mapping:column_meta(),
cquill@introspection:introspected_table()
) -> binary().
generate_field_definition(Col, Table) ->
Constraints = generate_constraints(Col, Table),
<<<<<<<<<<<<" #(\""/utf8, (erlang:element(6, Col))/binary>>/binary,
"\", \""/utf8>>/binary,
(render_field_type(erlang:element(2, Col)))/binary>>/binary,
"\", ["/utf8>>/binary,
Constraints/binary>>/binary,
"])"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 757).
-spec map_column_to_meta(
cquill@introspection:introspected_column(),
list(binary()),
generator_config()
) -> {ok, cquill@codegen@type_mapping:column_meta()} | {error, nil}.
map_column_to_meta(Col, Enum_names, Config) ->
case cquill@codegen@type_mapping:map_column(
erlang:element(2, Col),
erlang:element(4, Col),
erlang:element(5, Col),
erlang:element(6, Col),
erlang:element(7, Col),
Enum_names
) of
{ok, Meta} ->
Is_timestamp_field = gleam@list:contains(
erlang:element(4, Config),
erlang:element(2, Col)
),
Final_meta = case Is_timestamp_field of
true ->
{column_meta,
erlang:element(2, Meta),
true,
erlang:element(4, Meta),
erlang:element(5, Meta),
erlang:element(6, Meta),
erlang:element(7, Meta)};
false ->
Meta
end,
{ok, Final_meta};
{error, _} ->
{error, nil}
end.
-file("src/cquill/codegen/generator.gleam", 748).
-spec map_columns(
cquill@introspection:introspected_table(),
list(binary()),
generator_config()
) -> list(cquill@codegen@type_mapping:column_meta()).
map_columns(Table, Enum_names, Config) ->
_pipe = erlang:element(3, Table),
gleam@list:filter_map(
_pipe,
fun(Col) -> map_column_to_meta(Col, Enum_names, Config) end
).
-file("src/cquill/codegen/generator.gleam", 790).
?DOC(" Convert snake_case to PascalCase\n").
-spec pascal_case(binary()) -> binary().
pascal_case(Input) ->
cquill@codegen@type_mapping:pascal_case(Input).
-file("src/cquill/codegen/generator.gleam", 795).
?DOC(" Convert PascalCase to snake_case\n").
-spec snake_case(binary()) -> binary().
snake_case(Input) ->
cquill@codegen@type_mapping:snake_case(Input).
-file("src/cquill/codegen/generator.gleam", 244).
-spec generate_index_imports(
list(cquill@introspection:introspected_table()),
list(cquill@introspection:introspected_enum()),
generator_config()
) -> binary().
generate_index_imports(Tables, Enums, Config) ->
Table_imports = begin
_pipe = Tables,
gleam@list:map(
_pipe,
fun(Table) ->
Type_name = pascal_case(erlang:element(2, Table)),
Module_name = snake_case(erlang:element(2, Table)),
<<<<<<<<<<<<<<<<<<<<<<<<"import "/utf8,
(erlang:element(
2,
Config
))/binary>>/binary,
"/schema/"/utf8>>/binary,
Module_name/binary>>/binary,
".{"/utf8>>/binary,
Type_name/binary>>/binary,
", New"/utf8>>/binary,
Type_name/binary>>/binary,
", "/utf8>>/binary,
Type_name/binary>>/binary,
"Changes, "/utf8>>/binary,
Module_name/binary>>/binary,
"_schema}"/utf8>>
end
)
end,
Enum_import = case gleam@list:is_empty(Enums) of
true ->
[];
false ->
Enum_types = begin
_pipe@1 = Enums,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(E) -> pascal_case(erlang:element(2, E)) end
),
gleam@string:join(_pipe@2, <<", "/utf8>>)
end,
[<<<<<<<<"import "/utf8, (erlang:element(2, Config))/binary>>/binary,
"/enums.{"/utf8>>/binary,
Enum_types/binary>>/binary,
"}"/utf8>>]
end,
gleam@string:join(lists:append(Table_imports, Enum_import), <<"\n"/utf8>>).
-file("src/cquill/codegen/generator.gleam", 165).
?DOC(" Generate the index module that re-exports all schemas\n").
-spec generate_index_module(
list(cquill@introspection:introspected_table()),
list(cquill@introspection:introspected_enum()),
generator_config()
) -> generated_module().
generate_index_module(Tables, Enums, Config) ->
Content = <<<<(generate_index_module_header(Config))/binary, "\n"/utf8>>/binary,
(generate_index_imports(Tables, Enums, Config))/binary>>,
{generated_module,
<<(erlang:element(2, Config))/binary, "/schema"/utf8>>,
<<"schema.gleam"/utf8>>,
Content}.
-file("src/cquill/codegen/generator.gleam", 370).
-spec generate_schema_const(
cquill@introspection:introspected_table(),
list(cquill@codegen@type_mapping:column_meta()),
generator_config()
) -> binary().
generate_schema_const(Table, Columns, _) ->
Schema_name = <<(snake_case(erlang:element(2, Table)))/binary,
"_schema"/utf8>>,
Fields = begin
_pipe = Columns,
_pipe@1 = gleam@list:map(
_pipe,
fun(Col) -> generate_field_definition(Col, Table) end
),
gleam@string:join(_pipe@1, <<",\n"/utf8>>)
end,
Pk_str = begin
_pipe@2 = erlang:element(4, Table),
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Pk) -> <<<<"\""/utf8, Pk/binary>>/binary, "\""/utf8>> end
),
gleam@string:join(_pipe@3, <<", "/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"/// Schema metadata for "/utf8,
(erlang:element(
2,
Table
))/binary>>/binary,
"\n"/utf8>>/binary,
"pub const "/utf8>>/binary,
Schema_name/binary>>/binary,
" = Schema(\n"/utf8>>/binary,
" source: \""/utf8>>/binary,
(erlang:element(2, Table))/binary>>/binary,
"\",\n"/utf8>>/binary,
" fields: [\n"/utf8>>/binary,
Fields/binary>>/binary,
"\n ],\n"/utf8>>/binary,
" primary_key: ["/utf8>>/binary,
Pk_str/binary>>/binary,
"],\n"/utf8>>/binary,
")"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 501).
-spec generate_field_decoder(cquill@codegen@type_mapping:gleam_type()) -> binary().
generate_field_decoder(Gleam_type) ->
case Gleam_type of
gleam_int ->
<<"decoder.int()"/utf8>>;
gleam_float ->
<<"decoder.float()"/utf8>>;
gleam_string ->
<<"decoder.string()"/utf8>>;
gleam_bool ->
<<"decoder.bool()"/utf8>>;
gleam_bit_array ->
<<"decoder.bit_array()"/utf8>>;
gleam_time ->
<<"decoder.time()"/utf8>>;
gleam_date ->
<<"decoder.date()"/utf8>>;
gleam_time_of_day ->
<<"decoder.time_of_day()"/utf8>>;
gleam_decimal ->
<<"decoder.decimal()"/utf8>>;
gleam_uuid ->
<<"decoder.uuid()"/utf8>>;
gleam_json ->
<<"decoder.json()"/utf8>>;
{gleam_list, Element} ->
<<<<"decoder.list("/utf8, (generate_field_decoder(Element))/binary>>/binary,
")"/utf8>>;
{gleam_option, Inner} ->
<<<<"decoder.optional("/utf8,
(generate_field_decoder(Inner))/binary>>/binary,
")"/utf8>>;
{gleam_custom, _, Type_name} ->
<<(snake_case(Type_name))/binary, "_decoder()"/utf8>>
end.
-file("src/cquill/codegen/generator.gleam", 451).
-spec generate_decoder(
binary(),
list(cquill@codegen@type_mapping:column_meta())
) -> binary().
generate_decoder(Type_name, Columns) ->
Decoder_name = <<(snake_case(Type_name))/binary, "_decoder"/utf8>>,
Field_count = erlang:length(Columns),
Field_params = begin
_pipe = Columns,
_pipe@1 = gleam@list:index_map(
_pipe,
fun(Col, _) ->
<<<<" use "/utf8, (erlang:element(6, Col))/binary>>/binary,
" <- decoder.parameter"/utf8>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
Constructor_args = begin
_pipe@2 = Columns,
_pipe@3 = gleam@list:map(
_pipe@2,
fun(Col@1) -> <<(erlang:element(6, Col@1))/binary, ":"/utf8>> end
),
gleam@string:join(_pipe@3, <<", "/utf8>>)
end,
Field_decoders = begin
_pipe@4 = Columns,
_pipe@5 = gleam@list:index_map(
_pipe@4,
fun(Col@2, Idx) ->
<<<<<<<<" |> decoder.field("/utf8,
(erlang:integer_to_binary(Idx))/binary>>/binary,
", "/utf8>>/binary,
(generate_field_decoder(erlang:element(2, Col@2)))/binary>>/binary,
")"/utf8>>
end
),
gleam@string:join(_pipe@5, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<"/// Decoder for "/utf8,
Type_name/binary>>/binary,
" from database rows\n"/utf8>>/binary,
"pub fn "/utf8>>/binary,
Decoder_name/binary>>/binary,
"() {\n"/utf8>>/binary,
" decoder.into({\n"/utf8>>/binary,
Field_params/binary>>/binary,
"\n"/utf8>>/binary,
" "/utf8>>/binary,
Type_name/binary>>/binary,
"("/utf8>>/binary,
Constructor_args/binary>>/binary,
")\n"/utf8>>/binary,
" })\n"/utf8>>/binary,
Field_decoders/binary>>/binary,
"\n"/utf8>>/binary,
"}\n"/utf8>>/binary,
"\n"/utf8>>/binary,
"// Field count: "/utf8>>/binary,
(erlang:integer_to_binary(Field_count))/binary>>.
-file("src/cquill/codegen/generator.gleam", 589).
-spec generate_encoder_fn(cquill@codegen@type_mapping:gleam_type()) -> binary().
generate_encoder_fn(Gleam_type) ->
case Gleam_type of
gleam_int ->
<<"encoder.int"/utf8>>;
gleam_float ->
<<"encoder.float"/utf8>>;
gleam_string ->
<<"encoder.string"/utf8>>;
gleam_bool ->
<<"encoder.bool"/utf8>>;
gleam_bit_array ->
<<"encoder.bit_array"/utf8>>;
gleam_time ->
<<"encoder.time"/utf8>>;
gleam_date ->
<<"encoder.date"/utf8>>;
gleam_time_of_day ->
<<"encoder.time_of_day"/utf8>>;
gleam_decimal ->
<<"encoder.decimal"/utf8>>;
gleam_uuid ->
<<"encoder.uuid"/utf8>>;
gleam_json ->
<<"encoder.json"/utf8>>;
{gleam_list, _} ->
<<"encoder.list"/utf8>>;
{gleam_option, _} ->
<<"encoder.optional"/utf8>>;
{gleam_custom, _, Type_name} ->
<<(snake_case(Type_name))/binary, "_encoder"/utf8>>
end.
-file("src/cquill/codegen/generator.gleam", 564).
-spec generate_field_encoder(cquill@codegen@type_mapping:gleam_type(), binary()) -> binary().
generate_field_encoder(Gleam_type, Value_expr) ->
case Gleam_type of
gleam_int ->
<<<<"encoder.int("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_float ->
<<<<"encoder.float("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_string ->
<<<<"encoder.string("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_bool ->
<<<<"encoder.bool("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_bit_array ->
<<<<"encoder.bit_array("/utf8, Value_expr/binary>>/binary,
")"/utf8>>;
gleam_time ->
<<<<"encoder.time("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_date ->
<<<<"encoder.date("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_time_of_day ->
<<<<"encoder.time_of_day("/utf8, Value_expr/binary>>/binary,
")"/utf8>>;
gleam_decimal ->
<<<<"encoder.decimal("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_uuid ->
<<<<"encoder.uuid("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
gleam_json ->
<<<<"encoder.json("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{gleam_list, _} ->
<<<<"encoder.list("/utf8, Value_expr/binary>>/binary, ")"/utf8>>;
{gleam_option, Inner} ->
<<<<<<<<"encoder.optional("/utf8,
(generate_encoder_fn(Inner))/binary>>/binary,
", "/utf8>>/binary,
Value_expr/binary>>/binary,
")"/utf8>>;
{gleam_custom, _, Type_name} ->
<<<<<<(snake_case(Type_name))/binary, "_encoder("/utf8>>/binary,
Value_expr/binary>>/binary,
")"/utf8>>
end.
-file("src/cquill/codegen/generator.gleam", 526).
-spec generate_new_encoder(
binary(),
list(cquill@codegen@type_mapping:column_meta())
) -> binary().
generate_new_encoder(Type_name, Columns) ->
Encoder_name = <<<<"new_"/utf8, (snake_case(Type_name))/binary>>/binary,
"_encoder"/utf8>>,
Param_name = snake_case(Type_name),
Insert_columns = begin
_pipe = Columns,
gleam@list:filter(_pipe, fun(Col) -> not erlang:element(3, Col) end)
end,
Field_encoders = begin
_pipe@1 = Insert_columns,
_pipe@2 = gleam@list:map(
_pipe@1,
fun(Col@1) ->
<<<<<<<<" #(\""/utf8, (erlang:element(6, Col@1))/binary>>/binary,
"\", "/utf8>>/binary,
(generate_field_encoder(
erlang:element(2, Col@1),
<<<<Param_name/binary, "."/utf8>>/binary,
(erlang:element(6, Col@1))/binary>>
))/binary>>/binary,
"),"/utf8>>
end
),
gleam@string:join(_pipe@2, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<<<"/// Encoder for New"/utf8, Type_name/binary>>/binary,
"\n"/utf8>>/binary,
"pub fn "/utf8>>/binary,
Encoder_name/binary>>/binary,
"("/utf8>>/binary,
Param_name/binary>>/binary,
": New"/utf8>>/binary,
Type_name/binary>>/binary,
") {\n"/utf8>>/binary,
" [\n"/utf8>>/binary,
Field_encoders/binary>>/binary,
"\n ]\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 107).
?DOC(" Generate a complete schema module for a table\n").
-spec generate_schema_module(
cquill@introspection:introspected_table(),
list(cquill@introspection:introspected_enum()),
generator_config()
) -> generated_module().
generate_schema_module(Table, Enums, Config) ->
Enum_names = gleam@list:map(Enums, fun(E) -> erlang:element(2, E) end),
Columns = map_columns(Table, Enum_names, Config),
Type_name = pascal_case(erlang:element(2, Table)),
Module_name = snake_case(erlang:element(2, Table)),
Content = <<<<<<<<<<<<<<<<<<<<<<<<(generate_module_header(
erlang:element(2, Table),
Config
))/binary,
"\n"/utf8>>/binary,
(generate_imports(
Columns,
Config
))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_record_type(
Type_name,
Columns
))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_new_type(Type_name, Columns))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_changes_type(Type_name, Columns))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_schema_const(Table, Columns, Config))/binary>>/binary,
(case erlang:element(5, Config) of
true ->
<<"\n"/utf8, (generate_decoder(Type_name, Columns))/binary>>;
false ->
<<""/utf8>>
end)/binary>>/binary,
(case erlang:element(6, Config) of
true ->
<<"\n"/utf8, (generate_new_encoder(Type_name, Columns))/binary>>;
false ->
<<""/utf8>>
end)/binary>>,
{generated_module,
<<<<(erlang:element(2, Config))/binary, "/schema/"/utf8>>/binary,
Module_name/binary>>,
<<Module_name/binary, ".gleam"/utf8>>,
Content}.
-file("src/cquill/codegen/generator.gleam", 636).
-spec generate_enum_decoder(cquill@introspection:introspected_enum()) -> binary().
generate_enum_decoder(Enum_type) ->
Type_name = pascal_case(erlang:element(2, Enum_type)),
Decoder_name = <<(snake_case(erlang:element(2, Enum_type)))/binary,
"_decoder"/utf8>>,
Cases = begin
_pipe = erlang:element(3, Enum_type),
_pipe@1 = gleam@list:map(
_pipe,
fun(Value) ->
<<<<<<<<" \""/utf8, Value/binary>>/binary,
"\" -> Ok("/utf8>>/binary,
(pascal_case(Value))/binary>>/binary,
")"/utf8>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<<<"pub fn "/utf8, Decoder_name/binary>>/binary,
"() {\n"/utf8>>/binary,
" fn(dyn: Dynamic) {\n"/utf8>>/binary,
" use s <- result.try(dynamic.string(dyn))\n"/utf8>>/binary,
" case s {\n"/utf8>>/binary,
Cases/binary>>/binary,
"\n"/utf8>>/binary,
" _ -> Error([dynamic.DecodeError(expected: \""/utf8>>/binary,
Type_name/binary>>/binary,
"\", found: s, path: [])])\n"/utf8>>/binary,
" }\n"/utf8>>/binary,
" }\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 663).
-spec generate_enum_encoder(cquill@introspection:introspected_enum()) -> binary().
generate_enum_encoder(Enum_type) ->
Type_name = pascal_case(erlang:element(2, Enum_type)),
Encoder_name = <<(snake_case(erlang:element(2, Enum_type)))/binary,
"_encoder"/utf8>>,
Param_name = <<"value"/utf8>>,
Cases = begin
_pipe = erlang:element(3, Enum_type),
_pipe@1 = gleam@list:map(
_pipe,
fun(Value) ->
<<<<<<<<" "/utf8, (pascal_case(Value))/binary>>/binary,
" -> \""/utf8>>/binary,
Value/binary>>/binary,
"\""/utf8>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<"pub fn "/utf8, Encoder_name/binary>>/binary,
"("/utf8>>/binary,
Param_name/binary>>/binary,
": "/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {\n"/utf8>>/binary,
" case "/utf8>>/binary,
Param_name/binary>>/binary,
" {\n"/utf8>>/binary,
Cases/binary>>/binary,
"\n }\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 690).
-spec generate_enum_to_string(cquill@introspection:introspected_enum()) -> binary().
generate_enum_to_string(Enum_type) ->
Type_name = pascal_case(erlang:element(2, Enum_type)),
Fn_name = <<(snake_case(erlang:element(2, Enum_type)))/binary,
"_to_string"/utf8>>,
Param_name = <<"value"/utf8>>,
Cases = begin
_pipe = erlang:element(3, Enum_type),
_pipe@1 = gleam@list:map(
_pipe,
fun(Value) ->
<<<<<<<<" "/utf8, (pascal_case(Value))/binary>>/binary,
" -> \""/utf8>>/binary,
Value/binary>>/binary,
"\""/utf8>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>)
end,
<<<<<<<<<<<<<<<<<<<<<<<<"pub fn "/utf8, Fn_name/binary>>/binary, "("/utf8>>/binary,
Param_name/binary>>/binary,
": "/utf8>>/binary,
Type_name/binary>>/binary,
") -> String {\n"/utf8>>/binary,
" case "/utf8>>/binary,
Param_name/binary>>/binary,
" {\n"/utf8>>/binary,
Cases/binary>>/binary,
"\n }\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 612).
-spec generate_enum_type(cquill@introspection:introspected_enum()) -> binary().
generate_enum_type(Enum_type) ->
Type_name = pascal_case(erlang:element(2, Enum_type)),
Variants = begin
_pipe = erlang:element(3, Enum_type),
_pipe@1 = gleam@list:map(_pipe, fun pascal_case/1),
gleam@string:join(_pipe@1, <<"\n "/utf8>>)
end,
Decoder = generate_enum_decoder(Enum_type),
Encoder = generate_enum_encoder(Enum_type),
To_string_fn = generate_enum_to_string(Enum_type),
<<<<<<<<<<<<<<<<<<"pub type "/utf8, Type_name/binary>>/binary,
" {\n "/utf8>>/binary,
Variants/binary>>/binary,
"\n}\n\n"/utf8>>/binary,
Decoder/binary>>/binary,
"\n\n"/utf8>>/binary,
Encoder/binary>>/binary,
"\n\n"/utf8>>/binary,
To_string_fn/binary>>.
-file("src/cquill/codegen/generator.gleam", 146).
?DOC(" Generate the enum module containing all enum types\n").
-spec generate_enum_module(
list(cquill@introspection:introspected_enum()),
generator_config()
) -> generated_module().
generate_enum_module(Enums, Config) ->
Content = <<<<<<<<(generate_enum_module_header(Config))/binary, "\n"/utf8>>/binary,
(generate_enum_imports())/binary>>/binary,
"\n"/utf8>>/binary,
(gleam@string:join(
gleam@list:map(Enums, fun generate_enum_type/1),
<<"\n\n"/utf8>>
))/binary>>,
{generated_module,
<<(erlang:element(2, Config))/binary, "/enums"/utf8>>,
<<"enums.gleam"/utf8>>,
Content}.
-file("src/cquill/codegen/generator.gleam", 836).
?DOC(" Get the full file path for a generated module\n").
-spec module_file_path(generated_module()) -> binary().
module_file_path(Module) ->
<<<<"src/"/utf8, (erlang:element(2, Module))/binary>>/binary,
".gleam"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 875).
-spec generate_typed_module_header(binary(), generator_config()) -> binary().
generate_typed_module_header(Table_name, _) ->
<<<<<<<<<<<<"// "/utf8, Table_name/binary>>/binary,
".gleam (GENERATED)\n"/utf8>>/binary,
"//// Typed columns for "/utf8>>/binary,
Table_name/binary>>/binary,
" table\n"/utf8>>/binary,
"//// Generated by cquill - DO NOT EDIT\n"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 888).
-spec generate_typed_imports(list(cquill@codegen@type_mapping:column_meta())) -> binary().
generate_typed_imports(Columns) ->
Imports = cquill@codegen@type_mapping:collect_imports(Columns),
Base_import = <<"import cquill/typed/table.{type Table, type Column, table, column}"/utf8>>,
Type_imports = begin
_pipe = Imports,
gleam@list:filter_map(_pipe, fun(Imp) -> case Imp of
<<"gleam/option"/utf8>> ->
{ok, <<"import gleam/option.{type Option}"/utf8>>};
<<"birl"/utf8>> ->
{ok, <<"import birl.{type Time}"/utf8>>};
<<"uuid"/utf8>> ->
{ok, <<"import uuid.{type Uuid}"/utf8>>};
<<"decimal"/utf8>> ->
{ok, <<"import decimal.{type Decimal}"/utf8>>};
<<"gleam/json"/utf8>> ->
{ok, <<"import gleam/json.{type Json}"/utf8>>};
_ ->
{error, nil}
end end)
end,
All_imports = [Base_import | Type_imports],
gleam@string:join(All_imports, <<"\n"/utf8>>).
-file("src/cquill/codegen/generator.gleam", 913).
-spec generate_phantom_type(binary()) -> binary().
generate_phantom_type(Type_name) ->
<<<<<<<<"/// Phantom type for "/utf8, Type_name/binary>>/binary,
" table\n"/utf8>>/binary,
"pub type "/utf8>>/binary,
Type_name/binary>>.
-file("src/cquill/codegen/generator.gleam", 917).
-spec generate_table_constant(
cquill@introspection:introspected_table(),
binary(),
binary()
) -> binary().
generate_table_constant(Table, Fn_name, Type_name) ->
<<<<<<<<<<<<<<<<<<<<<<"/// Get a typed reference to the "/utf8,
(erlang:element(2, Table))/binary>>/binary,
" table\n"/utf8>>/binary,
"pub fn "/utf8>>/binary,
Fn_name/binary>>/binary,
"() -> Table("/utf8>>/binary,
Type_name/binary>>/binary,
") {\n"/utf8>>/binary,
" table(\""/utf8>>/binary,
(erlang:element(2, Table))/binary>>/binary,
"\")\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 945).
-spec generate_typed_column(cquill@codegen@type_mapping:column_meta(), binary()) -> binary().
generate_typed_column(Col, Type_name) ->
Col_name = erlang:element(6, Col),
Value_type = render_type(erlang:element(2, Col)),
<<<<<<<<<<<<<<<<<<<<<<<<<<"/// Column: "/utf8, Col_name/binary>>/binary,
"\n"/utf8>>/binary,
"pub fn "/utf8>>/binary,
Col_name/binary>>/binary,
"() -> Column("/utf8>>/binary,
Type_name/binary>>/binary,
", "/utf8>>/binary,
Value_type/binary>>/binary,
") {\n"/utf8>>/binary,
" column(\""/utf8>>/binary,
Col_name/binary>>/binary,
"\")\n"/utf8>>/binary,
"}"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 936).
-spec generate_typed_columns(
list(cquill@codegen@type_mapping:column_meta()),
binary()
) -> binary().
generate_typed_columns(Columns, Type_name) ->
_pipe = Columns,
_pipe@1 = gleam@list:map(
_pipe,
fun(Col) -> generate_typed_column(Col, Type_name) end
),
gleam@string:join(_pipe@1, <<"\n\n"/utf8>>).
-file("src/cquill/codegen/generator.gleam", 846).
?DOC(
" Generate a typed column module for a table\n"
" Creates phantom types and typed column constants for compile-time safety\n"
).
-spec generate_typed_module(
cquill@introspection:introspected_table(),
list(cquill@introspection:introspected_enum()),
generator_config()
) -> generated_module().
generate_typed_module(Table, Enums, Config) ->
Enum_names = gleam@list:map(Enums, fun(E) -> erlang:element(2, E) end),
Columns = map_columns(Table, Enum_names, Config),
Type_name = <<(pascal_case(erlang:element(2, Table)))/binary, "Table"/utf8>>,
Module_name = snake_case(erlang:element(2, Table)),
Table_fn_name = snake_case(erlang:element(2, Table)),
Content = <<<<<<<<<<<<<<<<(generate_typed_module_header(
erlang:element(2, Table),
Config
))/binary,
"\n"/utf8>>/binary,
(generate_typed_imports(Columns))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_phantom_type(Type_name))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_table_constant(Table, Table_fn_name, Type_name))/binary>>/binary,
"\n"/utf8>>/binary,
(generate_typed_columns(Columns, Type_name))/binary>>,
{generated_module,
<<<<(erlang:element(2, Config))/binary, "/typed/"/utf8>>/binary,
Module_name/binary>>,
<<Module_name/binary, ".gleam"/utf8>>,
Content}.
-file("src/cquill/codegen/generator.gleam", 982).
-spec generate_typed_index_module_header(generator_config()) -> binary().
generate_typed_index_module_header(_) ->
<<<<"// typed.gleam (GENERATED)\n"/utf8,
"//// Typed table and column definitions for type-safe queries\n"/utf8>>/binary,
"//// Generated by cquill - DO NOT EDIT\n"/utf8>>.
-file("src/cquill/codegen/generator.gleam", 988).
-spec generate_typed_index_imports(
list(cquill@introspection:introspected_table()),
generator_config()
) -> binary().
generate_typed_index_imports(Tables, Config) ->
_pipe = Tables,
_pipe@1 = gleam@list:map(
_pipe,
fun(Table) ->
Module_name = snake_case(erlang:element(2, Table)),
<<<<<<"import "/utf8, (erlang:element(2, Config))/binary>>/binary,
"/typed/"/utf8>>/binary,
Module_name/binary>>
end
),
gleam@string:join(_pipe@1, <<"\n"/utf8>>).
-file("src/cquill/codegen/generator.gleam", 966).
?DOC(" Generate the typed index module that re-exports all typed table modules\n").
-spec generate_typed_index_module(
list(cquill@introspection:introspected_table()),
generator_config()
) -> generated_module().
generate_typed_index_module(Tables, Config) ->
Content = <<<<(generate_typed_index_module_header(Config))/binary,
"\n"/utf8>>/binary,
(generate_typed_index_imports(Tables, Config))/binary>>,
{generated_module,
<<(erlang:element(2, Config))/binary, "/typed"/utf8>>,
<<"typed.gleam"/utf8>>,
Content}.
-file("src/cquill/codegen/generator.gleam", 804).
?DOC(" Generate all modules for a complete schema\n").
-spec generate_all(
list(cquill@introspection:introspected_table()),
list(cquill@introspection:introspected_enum()),
generator_config()
) -> list(generated_module()).
generate_all(Tables, Enums, Config) ->
Table_modules = begin
_pipe = Tables,
gleam@list:map(
_pipe,
fun(Table) -> generate_schema_module(Table, Enums, Config) end
)
end,
Enum_module = case gleam@list:is_empty(Enums) of
true ->
[];
false ->
[generate_enum_module(Enums, Config)]
end,
Index_module = [generate_index_module(Tables, Enums, Config)],
Typed_modules = case erlang:element(7, Config) of
true ->
Typed_table_modules = begin
_pipe@1 = Tables,
gleam@list:map(
_pipe@1,
fun(Table@1) ->
generate_typed_module(Table@1, Enums, Config)
end
)
end,
Typed_index = [generate_typed_index_module(Tables, Config)],
lists:append([Typed_table_modules, Typed_index]);
false ->
[]
end,
lists:append([Table_modules, Enum_module, Index_module, Typed_modules]).