-module(database@query). -compile([no_auto_import, nowarn_unused_vars]). -export([from/1, select/2, where/2, build/1, insert/1, update/2, delete/1]). -export_type(['query'/1]). -type 'query'(FUW) :: {'query', database@schema:schema(FUW), list(binary()), list(binary()), list(gleam@pgo:value())}. -spec from(database@schema:schema(FUZ)) -> 'query'(FUZ). from(Schema) -> {'query', Schema, [], [], []}. -spec select('query'(FVC), list(binary())) -> 'query'(FVC). select(Query, Fields) -> erlang:setelement( 3, Query, gleam@list:append(Fields, erlang:element(3, Query)) ). -spec where('query'(FVG), list({binary(), list(gleam@pgo:value())})) -> 'query'(FVG). where(Query, Bindings) -> Where@1 = begin _pipe = Bindings, _pipe@1 = gleam@list:map( _pipe, fun(Where) -> {Field, _} = Where, Field end ), gleam@list:append(_pipe@1, erlang:element(4, Query)) end, Bindings@1 = begin _pipe@2 = Bindings, _pipe@3 = gleam@list:flat_map( _pipe@2, fun(Where@2) -> {_, Value} = Where@2, Value end ), gleam@list:append(_pipe@3, erlang:element(5, Query)) end, erlang:setelement( 5, erlang:setelement( 4, Query, gleam@list:append(erlang:element(4, Query), Where@1) ), Bindings@1 ). -spec build_where(gleam@string_builder:string_builder(), list(binary())) -> gleam@string_builder:string_builder(). build_where(Query, Where) -> case Where of [] -> Query; Where@1 -> Where_fields = begin _pipe = Where@1, _pipe@1 = gleam@list:map( _pipe, fun(Field) -> gleam@string_builder:from_string(Field) end ), gleam@string_builder:join(_pipe@1, <<" AND "/utf8>>) end, _pipe@2 = Query, _pipe@3 = gleam@string_builder:append(_pipe@2, <<" WHERE "/utf8>>), gleam@string_builder:append_builder(_pipe@3, Where_fields) end. -spec build('query'(any())) -> binary(). build(Query) -> Select_fields = begin _pipe = erlang:element(3, Query), _pipe@1 = gleam@list:map( _pipe, fun(Field) -> gleam@string_builder:from_string(Field) end ), gleam@string_builder:join(_pipe@1, <<", "/utf8>>) end, _pipe@2 = gleam@string_builder:new(), _pipe@3 = gleam@string_builder:append(_pipe@2, <<"SELECT "/utf8>>), _pipe@4 = gleam@string_builder:append_builder(_pipe@3, Select_fields), _pipe@5 = gleam@string_builder:append(_pipe@4, <<" FROM "/utf8>>), _pipe@6 = gleam@string_builder:append( _pipe@5, erlang:element(2, erlang:element(2, Query)) ), _pipe@7 = build_where(_pipe@6, erlang:element(4, Query)), gleam@string_builder:to_string(_pipe@7). -spec insert(database@schema:schema(any())) -> binary(). insert(Schema) -> Fields = gleam@list:filter_map( erlang:element(4, Schema), fun(Field) -> case erlang:element(2, Field) =:= erlang:element(3, Schema) of true -> {error, nil}; false -> {ok, gleam@string_builder:from_string( erlang:element(2, Field) )} end end ), Replacements = gleam@list:index_map( Fields, fun(I, _) -> gleam@string_builder:from_string( <<"$"/utf8, (gleam@int:to_string(I + 1))/binary>> ) end ), _pipe = gleam@string_builder:new(), _pipe@1 = gleam@string_builder:append(_pipe, <<"INSERT INTO "/utf8>>), _pipe@2 = gleam@string_builder:append(_pipe@1, erlang:element(2, Schema)), _pipe@3 = gleam@string_builder:append(_pipe@2, <<"("/utf8>>), _pipe@4 = gleam@string_builder:append_builder( _pipe@3, gleam@string_builder:join(Fields, <<", "/utf8>>) ), _pipe@5 = gleam@string_builder:append(_pipe@4, <<") VALUES ("/utf8>>), _pipe@6 = gleam@string_builder:append_builder( _pipe@5, gleam@string_builder:join(Replacements, <<", "/utf8>>) ), _pipe@7 = gleam@string_builder:append(_pipe@6, <<") RETURNING *"/utf8>>), gleam@string_builder:to_string(_pipe@7). -spec update('query'(any()), list({binary(), gleam@pgo:value()})) -> binary(). update(Query, Fields) -> Offset = gleam@list:length(erlang:element(5, Query)), Updates = gleam@list:index_map( Fields, fun(I, Field) -> {Field@1, _} = Field, gleam@string_builder:from_string( <<<>/binary, (gleam@int:to_string((I + Offset) + 1))/binary>> ) end ), _pipe = gleam@string_builder:new(), _pipe@1 = gleam@string_builder:append(_pipe, <<"UPDATE "/utf8>>), _pipe@2 = gleam@string_builder:append( _pipe@1, erlang:element(2, erlang:element(2, Query)) ), _pipe@3 = gleam@string_builder:append(_pipe@2, <<" SET "/utf8>>), _pipe@4 = gleam@string_builder:append_builder( _pipe@3, gleam@string_builder:join(Updates, <<", "/utf8>>) ), _pipe@5 = build_where(_pipe@4, erlang:element(4, Query)), _pipe@6 = gleam@string_builder:append(_pipe@5, <<" RETURNING *"/utf8>>), gleam@string_builder:to_string(_pipe@6). -spec delete('query'(any())) -> binary(). delete(Query) -> _pipe = gleam@string_builder:new(), _pipe@1 = gleam@string_builder:append(_pipe, <<"DELETE FROM "/utf8>>), _pipe@2 = gleam@string_builder:append( _pipe@1, erlang:element(2, erlang:element(2, Query)) ), _pipe@3 = build_where(_pipe@2, erlang:element(4, Query)), _pipe@4 = gleam@string_builder:append(_pipe@3, <<" RETURNING *"/utf8>>), gleam@string_builder:to_string(_pipe@4).