Packages
gleam_mongo
0.2.0
0.18.1
retired
0.18.0
retired
0.17.0
retired
0.16.0
retired
0.15.1
retired
0.15.0
retired
0.14.0
retired
0.13.0
retired
0.12.0
retired
0.11.0
retired
0.10.0
retired
0.9.0
retired
0.8.0
retired
0.7.0
retired
0.6.0
retired
0.5.0
retired
0.4.0
retired
0.3.0
0.2.0
retired
0.1.3
retired
0.1.2
retired
0.1.1
retired
0.1.0
retired
A mongodb driver for gleam
Retired package: Renamed - Republished as mungo
Current section
Files
Jump to
Current section
Files
src/mongo@client.erl
-module(mongo@client).
-compile(no_auto_import).
-export([connect/1, collection/2, execute/2]).
-export_type([auth/0, connection_info/0, database/0, collection/0]).
-opaque auth() :: {auth, binary(), binary()}.
-opaque connection_info() :: {connection_info,
binary(),
integer(),
binary(),
gleam@option:option(auth()),
gleam@option:option(binary())}.
-opaque database() :: {database, tcp:socket(), binary()}.
-type collection() :: {collection, database(), binary()}.
-spec connect(binary()) -> {ok, database()} | {error, nil}.
connect(Uri) ->
case parse_connection_string(Uri) of
{ok, Info} ->
case Info of
{connection_info, Host, Port, Db, _@1, _@2} ->
case tcp:connect(Host, Port) of
{ok, Socket} ->
{ok, {database, Socket, Db}};
{error, _@3} ->
{error, nil}
end
end;
{error, nil} ->
{error, nil}
end.
-spec collection(database(), binary()) -> collection().
collection(Db, Name) ->
{collection, Db, Name}.
-spec execute(collection(), bson@types:value()) -> {ok,
list({binary(),
bson@types:value()})} |
{error, {integer(), binary()}}.
execute(Collection, Cmd) ->
case erlang:element(2, Collection) of
{database, Socket, Name} ->
case begin
_pipe = Socket,
send_cmd(_pipe, Name, Cmd)
end of
{ok,
[{<<"ok"/utf8>>, {double, 0.0}},
{<<"errmsg"/utf8>>, {str, Msg}},
{<<"code"/utf8>>, {integer, Code}},
{<<"codeName"/utf8>>, _@1}]} ->
{error, {Code, Msg}};
{ok, Result} ->
{ok, Result};
{error, nil} ->
{error, {-2, <<""/utf8>>}}
end
end.
-spec parse_connection_string(binary()) -> {ok, connection_info()} |
{error, nil}.
parse_connection_string(Uri) ->
case gleam@uri:parse(Uri) of
{ok, Parsed} ->
case erlang:element(2, Parsed) of
{some, <<"mongodb"/utf8>>} ->
case erlang:element(4, Parsed) of
{some, <<""/utf8>>} ->
{error, nil};
{some, Host} ->
Port = begin
_pipe = erlang:element(5, Parsed),
gleam@option:unwrap(_pipe, 27017)
end,
case erlang:element(6, Parsed) of
<<""/utf8>> ->
{error, nil};
<<"/"/utf8>> ->
{error, nil};
Path ->
[_@1, Db] = gleam@string:split(
Path,
<<"/"/utf8>>
),
case erlang:element(3, Parsed) of
{some, Userinfo} ->
case gleam@string:split(
Userinfo,
<<":"/utf8>>
) of
[<<""/utf8>>, _@2] ->
{error, nil};
[_@3, <<""/utf8>>] ->
{error, nil};
[Username, Password] ->
case erlang:element(
7,
Parsed
) of
{some, Query} ->
case begin
_pipe@1 = Query,
gleam@uri:parse_query(
_pipe@1
)
end of
{ok, Opts} ->
case gleam@list:key_find(
Opts,
<<"authSource"/utf8>>
) of
{ok,
Auth_source} ->
{ok,
{connection_info,
Host,
Port,
Db,
{some,
{auth,
Username,
Password}},
{some,
Auth_source}}};
{error,
nil} ->
{ok,
{connection_info,
Host,
Port,
Db,
{some,
{auth,
Username,
Password}},
none}}
end;
{error, nil} ->
{error, nil}
end;
none ->
{ok,
{connection_info,
Host,
Port,
Db,
{some,
{auth,
Username,
Password}},
none}}
end;
_@4 ->
{error, nil}
end;
none ->
{ok,
{connection_info,
Host,
Port,
Db,
none,
none}}
end
end;
none ->
{error, nil}
end;
{some, _@5} ->
{error, nil};
none ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end.
-spec send_cmd(tcp:socket(), binary(), bson@types:value()) -> {ok,
list({binary(),
bson@types:value()})} |
{error, nil}.
send_cmd(Socket, Db, Cmd) ->
{document, Cmd@2} = case Cmd of
{document, Cmd@1} -> {document, Cmd@1};
_try ->
erlang:error(#{gleam_error => assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _try,
module => <<"mongo/client"/utf8>>,
function => <<"send_cmd"/utf8>>,
line => 160})
end,
Cmd@3 = gleam@list:append(Cmd@2, [{<<"$db"/utf8>>, {str, Db}}]),
Encoded = bson:encode(Cmd@3),
Size = gleam@bit_string:byte_size(Encoded) + 21,
Packet = begin
_pipe = [<<Size:32/little, 0:32, 0:32, 2013:32/little, 0:32, 0>>,
Encoded],
gleam@bit_string:concat(_pipe)
end,
case begin
_pipe@1 = Socket,
tcp:send(_pipe@1, Packet)
end of
ok ->
case begin
_pipe@2 = Socket,
tcp:'receive'(_pipe@2)
end of
{ok, Response} ->
<<_@1:168, Rest/bitstring>> = Response,
Rest,
case bson:decode(Rest) of
{ok, Result} ->
{ok, Result};
{error, nil} ->
{error, nil}
end;
{error, nil} ->
{error, nil}
end;
_@2 ->
{error, nil}
end.