Packages
gleam_mongo
0.17.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@crud.erl
-module(mongo@crud).
-compile([no_auto_import, nowarn_unused_vars]).
-export([count_all/1, count/2, find_many/3, find_one/3, find_by_id/2, find_all/2, update_one/4, update_many/4, delete_one/2, delete_many/2, insert_many/2, insert_one/2]).
-export_type([insert_result/0, update_result/0]).
-type insert_result() :: {insert_result, integer(), list(bson@value:value())}.
-type update_result() :: {update_result, integer(), integer()} |
{upsert_result, integer(), bson@value:value()}.
-spec count_all(mongo@client:collection()) -> {ok, integer()} |
{error, mongo@utils:mongo_error()}.
count_all(Collection) ->
case begin
_pipe = Collection,
mongo@client:execute(
_pipe,
{document,
[{<<"count"/utf8>>, {str, erlang:element(3, Collection)}}]}
)
end of
{ok, [{<<"n"/utf8>>, {integer, N}}, {<<"ok"/utf8>>, Ok}]} ->
case Ok of
{double, 1.0} ->
{ok, N};
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code, Msg}} ->
{error, {mongo_error, Code, Msg, null}}
end.
-spec validate_doc(bson@value:value()) -> boolean().
validate_doc(Candidate) ->
case Candidate of
{document, _} ->
true;
_ ->
false
end.
-spec count(mongo@client:collection(), bson@value:value()) -> {ok, integer()} |
{error, mongo@utils:mongo_error()}.
count(Collection, Filter) ->
gleam@bool:guard(
not validate_doc(Filter),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
case begin
_pipe = Collection,
mongo@client:execute(
_pipe,
{document,
[{<<"count"/utf8>>,
{str, erlang:element(3, Collection)}},
{<<"query"/utf8>>, Filter}]}
)
end of
{ok, [{<<"n"/utf8>>, {integer, N}}, {<<"ok"/utf8>>, Ok}]} ->
case Ok of
{double, 1.0} ->
{ok, N};
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code, Msg}} ->
{error, {mongo_error, Code, Msg, null}}
end
end
).
-spec find(
mongo@client:collection(),
bson@value:value(),
list(mongo@utils:find_option())
) -> {ok, list(bson@value:value())} | {error, mongo@utils:mongo_error()}.
find(Collection, Filter, Options) ->
gleam@bool:guard(
not validate_doc(Filter),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
Body = gleam@list:fold(
Options,
[{<<"find"/utf8>>, {str, erlang:element(3, Collection)}},
{<<"filter"/utf8>>, Filter}],
fun(Acc, Opt) -> case Opt of
{sort, {document, Sort}} ->
gleam@list:key_set(
Acc,
<<"sort"/utf8>>,
{document, Sort}
);
{projection, {document, Projection}} ->
gleam@list:key_set(
Acc,
<<"projection"/utf8>>,
{document, Projection}
);
{skip, Skip} ->
gleam@list:key_set(
Acc,
<<"skip"/utf8>>,
{integer, Skip}
);
{limit, Limit} ->
gleam@list:key_set(
Acc,
<<"limit"/utf8>>,
{integer, Limit}
)
end end
),
case begin
_pipe = Collection,
mongo@client:execute(_pipe, {document, Body})
end of
{ok, Result} ->
[{<<"cursor"/utf8>>, {document, Result@1}},
{<<"ok"/utf8>>, Ok}] = Result,
_assert_subject = gleam@list:key_find(
Result@1,
<<"firstBatch"/utf8>>
),
{ok, {array, Docs}} = case _assert_subject of
{ok, {array, _}} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mongo/crud"/utf8>>,
function => <<"find"/utf8>>,
line => 240})
end,
case Ok of
{double, 1.0} ->
{ok, Docs};
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code, Msg}} ->
{error, {mongo_error, Code, Msg, null}}
end
end
).
-spec find_many(
mongo@client:collection(),
bson@value:value(),
list(mongo@utils:find_option())
) -> {ok, list(bson@value:value())} | {error, mongo@utils:mongo_error()}.
find_many(Collection, Filter, Options) ->
_pipe = Collection,
find(_pipe, Filter, Options).
-spec find_one(
mongo@client:collection(),
bson@value:value(),
bson@value:value()
) -> {ok, bson@value:value()} | {error, mongo@utils:mongo_error()}.
find_one(Collection, Filter, Projection) ->
gleam@bool:guard(
not validate_doc(Filter),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
gleam@bool:guard(
not validate_doc(Projection),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
case begin
_pipe = Collection,
find_many(
_pipe,
Filter,
[{limit, 1}, {projection, Projection}]
)
end of
{ok, []} ->
{ok, null};
{ok, [Doc]} ->
{ok, Doc};
{error, Error} ->
{error, Error}
end
end
)
end
).
-spec find_by_id(mongo@client:collection(), binary()) -> {ok,
bson@value:value()} |
{error, mongo@utils:mongo_error()}.
find_by_id(Collection, Id) ->
case bson@object_id:from_string(Id) of
{ok, Id@1} ->
_pipe = Collection,
find_one(
_pipe,
{document, [{<<"_id"/utf8>>, {object_id, Id@1}}]},
{document, []}
);
{error, nil} ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end.
-spec find_all(mongo@client:collection(), list(mongo@utils:find_option())) -> {ok,
list(bson@value:value())} |
{error, mongo@utils:mongo_error()}.
find_all(Collection, Options) ->
_pipe = Collection,
find(_pipe, {document, []}, Options).
-spec update(
mongo@client:collection(),
bson@value:value(),
bson@value:value(),
list(mongo@utils:update_option()),
boolean()
) -> {ok, update_result()} | {error, mongo@utils:mongo_error()}.
update(Collection, Filter, Change, Options, Multi) ->
gleam@bool:guard(
not validate_doc(Filter),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
gleam@bool:guard(
not validate_doc(Change),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
Update = [{<<"q"/utf8>>, Filter},
{<<"u"/utf8>>, Change},
{<<"multi"/utf8>>, {boolean, Multi}}],
Update@1 = begin
_pipe = gleam@list:fold(
Options,
Update,
fun(Acc, Opt) -> case Opt of
upsert ->
gleam@list:key_set(
Acc,
<<"upsert"/utf8>>,
{boolean, true}
);
{array_filters, Filters} ->
gleam@list:key_set(
Acc,
<<"arrayFilters"/utf8>>,
{array, Filters}
)
end end
),
{document, _pipe}
end,
case begin
_pipe@1 = Collection,
mongo@client:execute(
_pipe@1,
{document,
[{<<"update"/utf8>>,
{str, erlang:element(3, Collection)}},
{<<"updates"/utf8>>, {array, [Update@1]}}]}
)
end of
{ok,
[{<<"n"/utf8>>, {integer, N}},
{<<"nModified"/utf8>>, {integer, Modified}},
{<<"ok"/utf8>>, Ok}]} ->
case Ok of
{double, 1.0} ->
{ok, {update_result, N, Modified}};
_ ->
{error,
{mongo_error, -16, <<""/utf8>>, null}}
end;
{ok,
[{<<"n"/utf8>>, {integer, N@1}},
{<<"upserted"/utf8>>,
{array,
[{document,
[{<<"index"/utf8>>, _},
{<<"_id"/utf8>>, Upserted}]}]}},
{<<"nModified"/utf8>>, _},
{<<"ok"/utf8>>, Ok@1}]} ->
case Ok@1 of
{double, 1.0} ->
{ok, {upsert_result, N@1, Upserted}};
_ ->
{error,
{mongo_error, -16, <<""/utf8>>, null}}
end;
{ok,
[{<<"n"/utf8>>, _},
{<<"writeErrors"/utf8>>, {array, Errors}},
{<<"nModified"/utf8>>, _},
{<<"ok"/utf8>>, Ok@2}]} ->
case Ok@2 of
{double, 1.0} ->
_assert_subject = gleam@list:first(Errors),
{ok, Error} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(
#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mongo/crud"/utf8>>,
function => <<"update"/utf8>>,
line => 316}
)
end,
case Error of
{document,
[{<<"index"/utf8>>, _},
{<<"code"/utf8>>,
{integer, Code}},
{<<"keyPattern"/utf8>>, _},
{<<"keyValue"/utf8>>, Source},
{<<"errmsg"/utf8>>, {str, Msg}}]} ->
{error,
{mongo_error, Code, Msg, Source}};
_ ->
{error,
{mongo_error,
-16,
<<""/utf8>>,
null}}
end;
_ ->
{error,
{mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code@1, Msg@1}} ->
{error, {mongo_error, Code@1, Msg@1, null}}
end
end
)
end
).
-spec update_one(
mongo@client:collection(),
bson@value:value(),
bson@value:value(),
list(mongo@utils:update_option())
) -> {ok, update_result()} | {error, mongo@utils:mongo_error()}.
update_one(Collection, Filter, Change, Options) ->
_pipe = Collection,
update(_pipe, Filter, Change, Options, false).
-spec update_many(
mongo@client:collection(),
bson@value:value(),
bson@value:value(),
list(mongo@utils:update_option())
) -> {ok, update_result()} | {error, mongo@utils:mongo_error()}.
update_many(Collection, Filter, Change, Options) ->
_pipe = Collection,
update(_pipe, Filter, Change, Options, true).
-spec delete(mongo@client:collection(), bson@value:value(), boolean()) -> {ok,
integer()} |
{error, mongo@utils:mongo_error()}.
delete(Collection, Filter, Multi) ->
gleam@bool:guard(
not validate_doc(Filter),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
case begin
_pipe = Collection,
mongo@client:execute(
_pipe,
{document,
[{<<"delete"/utf8>>,
{str, erlang:element(3, Collection)}},
{<<"deletes"/utf8>>,
{array,
[{document,
[{<<"q"/utf8>>, Filter},
{<<"limit"/utf8>>,
{integer, case Multi of
true ->
0;
false ->
1
end}}]}]}}]}
)
end of
{ok, [{<<"n"/utf8>>, {integer, N}}, {<<"ok"/utf8>>, Ok}]} ->
case Ok of
{double, 1.0} ->
{ok, N};
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{ok,
[{<<"n"/utf8>>, _},
{<<"writeErrors"/utf8>>, {array, Errors}},
{<<"ok"/utf8>>, Ok@1}]} ->
case Ok@1 of
{double, 1.0} ->
_assert_subject = gleam@list:first(Errors),
{ok, Error} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mongo/crud"/utf8>>,
function => <<"delete"/utf8>>,
line => 367})
end,
case Error of
{document,
[{<<"index"/utf8>>, _},
{<<"code"/utf8>>, {integer, Code}},
{<<"keyPattern"/utf8>>, _},
{<<"keyValue"/utf8>>, Source},
{<<"errmsg"/utf8>>, {str, Msg}}]} ->
{error, {mongo_error, Code, Msg, Source}};
_ ->
{error,
{mongo_error, -16, <<""/utf8>>, null}}
end;
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code@1, Msg@1}} ->
{error, {mongo_error, Code@1, Msg@1, null}}
end
end
).
-spec delete_one(mongo@client:collection(), bson@value:value()) -> {ok,
integer()} |
{error, mongo@utils:mongo_error()}.
delete_one(Collection, Filter) ->
_pipe = Collection,
delete(_pipe, Filter, false).
-spec delete_many(mongo@client:collection(), bson@value:value()) -> {ok,
integer()} |
{error, mongo@utils:mongo_error()}.
delete_many(Collection, Filter) ->
_pipe = Collection,
delete(_pipe, Filter, true).
-spec validate_all_docs(list(bson@value:value())) -> boolean().
validate_all_docs(Candidates) ->
gleam@list:all(Candidates, fun validate_doc/1).
-spec insert_many(mongo@client:collection(), list(bson@value:value())) -> {ok,
insert_result()} |
{error, mongo@utils:mongo_error()}.
insert_many(Collection, Docs) ->
gleam@bool:guard(
not validate_all_docs(Docs),
{error, {mongo_error, -16, <<""/utf8>>, null}},
fun() ->
Docs@1 = gleam@list:map(Docs, fun(D) -> case D of
{document, Fields} ->
case gleam@list:find(
Fields,
fun(Kv) ->
gleam@pair:first(Kv) =:= <<"_id"/utf8>>
end
) of
{ok, _} ->
D;
{error, nil} ->
Id = bson@object_id:new(),
Fields@1 = gleam@list:prepend(
Fields,
{<<"_id"/utf8>>, {object_id, Id}}
),
{document, Fields@1}
end;
_ ->
D
end end),
Inserted_ids = gleam@list:map(Docs@1, fun(D@1) -> case D@1 of
{document, Fields@2} ->
case gleam@list:find(
Fields@2,
fun(Kv@1) ->
gleam@pair:first(Kv@1) =:= <<"_id"/utf8>>
end
) of
{ok, {_, Id@1}} ->
Id@1;
_ ->
{str, <<""/utf8>>}
end;
_ ->
{str, <<""/utf8>>}
end end),
case begin
_pipe = Collection,
mongo@client:execute(
_pipe,
{document,
[{<<"insert"/utf8>>,
{str, erlang:element(3, Collection)}},
{<<"documents"/utf8>>, {array, Docs@1}}]}
)
end of
{ok, [{<<"n"/utf8>>, {integer, N}}, {<<"ok"/utf8>>, Ok}]} ->
case Ok of
{double, 1.0} ->
{ok, {insert_result, N, Inserted_ids}};
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{ok,
[{<<"n"/utf8>>, _},
{<<"writeErrors"/utf8>>, {array, Errors}},
{<<"ok"/utf8>>, Ok@1}]} ->
case Ok@1 of
{double, 1.0} ->
_assert_subject = gleam@list:first(Errors),
{ok, Error} = case _assert_subject of
{ok, _} -> _assert_subject;
_assert_fail ->
erlang:error(#{gleam_error => let_assert,
message => <<"Assertion pattern match failed"/utf8>>,
value => _assert_fail,
module => <<"mongo/crud"/utf8>>,
function => <<"insert_many"/utf8>>,
line => 192})
end,
case Error of
{document,
[{<<"index"/utf8>>, _},
{<<"code"/utf8>>, {integer, Code}},
{<<"keyPattern"/utf8>>, _},
{<<"keyValue"/utf8>>, Source},
{<<"errmsg"/utf8>>, {str, Msg}}]} ->
{error, {mongo_error, Code, Msg, Source}};
_ ->
{error,
{mongo_error, -16, <<""/utf8>>, null}}
end;
_ ->
{error, {mongo_error, -16, <<""/utf8>>, null}}
end;
{error, {Code@1, Msg@1}} ->
{error, {mongo_error, Code@1, Msg@1, null}}
end
end
).
-spec insert_one(mongo@client:collection(), bson@value:value()) -> {ok,
bson@value:value()} |
{error, mongo@utils:mongo_error()}.
insert_one(Collection, Doc) ->
case begin
_pipe = Collection,
insert_many(_pipe, [Doc])
end of
{ok, {insert_result, _, [Id]}} ->
{ok, Id};
{error, Error} ->
{error, Error}
end.