Skip to content

Commit

Permalink
feat: add support for Elixir 1.15 (#195)
Browse files Browse the repository at this point in the history
  • Loading branch information
zookzook committed Jul 30, 2023
1 parent 174c7d9 commit f621a62
Show file tree
Hide file tree
Showing 13 changed files with 68 additions and 53 deletions.
4 changes: 2 additions & 2 deletions .tool-versions
@@ -1,3 +1,3 @@
elixir 1.13.4-otp-25
erlang 25.0.3
elixir 1.15.4-otp-26
erlang 26.0.2
python 3.10.2
1 change: 0 additions & 1 deletion config/dev.exs
@@ -1 +0,0 @@

1 change: 0 additions & 1 deletion config/prod.exs
@@ -1 +0,0 @@

22 changes: 11 additions & 11 deletions lib/bson/decoder.ex
Expand Up @@ -32,11 +32,11 @@ defmodule BSON.Decoder do
{:NaN, rest}
end

defp type(@type_float, <<float::little-float64, rest::binary>>) do
defp type(@type_float, <<float::little-float64(), rest::binary>>) do
{float, rest}
end

defp type(@type_string, <<size::int32, rest::binary>>) do
defp type(@type_string, <<size::int32(), rest::binary>>) do
size = size - 1
<<string::binary(size), 0x00, rest::binary>> = rest
{string, rest}
Expand All @@ -50,12 +50,12 @@ defmodule BSON.Decoder do
list(binary)
end

defp type(@type_binary, <<_size::int32, subtype, length::int32, binary::binary(length), rest::binary>>) when subtype == 0x02 do
defp type(@type_binary, <<_size::int32(), subtype, length::int32(), binary::binary(length), rest::binary>>) when subtype == 0x02 do
subtype = subtype(subtype)
{%BSON.Binary{binary: binary, subtype: subtype}, rest}
end

defp type(@type_binary, <<size::int32, subtype, binary::binary(size), rest::binary>>) do
defp type(@type_binary, <<size::int32(), subtype, binary::binary(size), rest::binary>>) do
subtype = subtype(subtype)
{%BSON.Binary{binary: binary, subtype: subtype}, rest}
end
Expand All @@ -72,7 +72,7 @@ defmodule BSON.Decoder do
{true, rest}
end

defp type(@type_datetime, <<unix_ms::int64, rest::binary>>) do
defp type(@type_datetime, <<unix_ms::int64(), rest::binary>>) do
{DateTime.from_unix!(unix_ms, :millisecond), rest}
end

Expand All @@ -99,23 +99,23 @@ defmodule BSON.Decoder do
type(@type_string, binary)
end

defp type(@type_js_scope, <<size::int32, binary::binary>>) do
defp type(@type_js_scope, <<size::int32(), binary::binary>>) do
size = size - 4
<<binary::binary(size), rest::binary>> = binary
{code, binary} = type(@type_string, binary)
{scope, ""} = document(binary)
{%BSON.JavaScript{code: code, scope: scope}, rest}
end

defp type(@type_int32, <<int::int32, rest::binary>>) do
defp type(@type_int32, <<int::int32(), rest::binary>>) do
{int, rest}
end

defp type(@type_timestamp, <<ordinal::int32, epoch::int32, rest::binary>>) do
defp type(@type_timestamp, <<ordinal::int32(), epoch::int32(), rest::binary>>) do
{%BSON.Timestamp{value: epoch, ordinal: ordinal}, rest}
end

defp type(@type_int64, <<int::int64, rest::binary>>) do
defp type(@type_int64, <<int::int64(), rest::binary>>) do
{int, rest}
end

Expand All @@ -131,7 +131,7 @@ defmodule BSON.Decoder do
{:BSON_max, rest}
end

def document(<<size::int32, rest::binary>>) do
def document(<<size::int32(), rest::binary>>) do
size = size - 5
<<doc::binary(size), 0x00, rest::binary>> = rest

Expand All @@ -149,7 +149,7 @@ defmodule BSON.Decoder do
acc |> Enum.reverse() |> Enum.into(%{})
end

defp list(<<size::int32, rest::binary>>) do
defp list(<<size::int32(), rest::binary>>) do
size = size - 5
<<list::binary(size), 0x00, rest::binary>> = rest

Expand Down
22 changes: 11 additions & 11 deletions lib/bson/encoder.ex
Expand Up @@ -20,20 +20,20 @@ defmodule BSON.Encoder do
def encode(%BSON.Binary{binary: binary, subtype: :binary_old}) do
subtype = subtype(:binary_old)
size = IO.iodata_length(binary)
[<<size + 4::int32>>, subtype, <<size::int32>>, binary]
[<<size + 4::int32()>>, subtype, <<size::int32()>>, binary]
end

def encode(%BSON.Binary{binary: binary, subtype: subtype}) do
subtype = subtype(subtype)
[<<IO.iodata_length(binary)::int32>>, subtype | binary]
[<<IO.iodata_length(binary)::int32()>>, subtype | binary]
end

def encode(%BSON.ObjectId{value: <<_::binary(12)>> = value}),
do: value

def encode(%DateTime{} = datetime) do
unix_ms = DateTime.to_unix(datetime, :millisecond)
<<unix_ms::int64>>
<<unix_ms::int64()>>
end

def encode(%BSON.Regex{pattern: pattern, options: options}),
Expand All @@ -45,13 +45,13 @@ defmodule BSON.Encoder do
def encode(%BSON.JavaScript{code: code, scope: scope}) do
iodata = [encode(code), document(scope)]
size = IO.iodata_length(iodata) + 4
[<<size::int32>> | iodata]
[<<size::int32()>> | iodata]
end

def encode(%BSON.Timestamp{value: epoch, ordinal: ordinal}),
do: <<ordinal::int32, epoch::int32>>
do: <<ordinal::int32(), epoch::int32()>>

def encode(%BSON.LongNumber{value: value}), do: <<value::int64>>
def encode(%BSON.LongNumber{value: value}), do: <<value::int64()>>

def encode(%Decimal{} = value), do: BSON.Decimal128.encode(value)

Expand Down Expand Up @@ -85,16 +85,16 @@ defmodule BSON.Encoder do
do: encode(Atom.to_string(value))

def encode(value) when is_binary(value),
do: [<<byte_size(value) + 1::int32>>, value, 0x00]
do: [<<byte_size(value) + 1::int32()>>, value, 0x00]

def encode(value) when is_float(value),
do: <<value::little-float64>>
do: <<value::little-float64()>>

def encode(value) when is_int32(value),
do: <<value::int32>>
do: <<value::int32()>>

def encode(value) when is_int64(value),
do: <<value::int64>>
do: <<value::int64()>>

def encode(value) do
raise Mongo.Error.exception("invalid document: #{inspect(value)}")
Expand Down Expand Up @@ -131,7 +131,7 @@ defmodule BSON.Encoder do
{key_type, [acc, type, key, value]}
end)

[<<IO.iodata_length(iodata) + 5::int32>>, iodata, 0x00]
[<<IO.iodata_length(iodata) + 5::int32()>>, iodata, 0x00]
end

defp cstring(string), do: [string, 0x00]
Expand Down
26 changes: 13 additions & 13 deletions lib/mongo/messages.ex
Expand Up @@ -62,7 +62,7 @@ defmodule Mongo.Messages do
end
end

def decode_header(<<length::int32, request_id::int32, response_to::int32, op_code::int32>>) do
def decode_header(<<length::int32(), request_id::int32(), response_to::int32(), op_code::int32()>>) do
header = msg_header(length: length - @header_size, request_id: request_id, response_to: response_to, op_code: op_code)
{:ok, header}
end
Expand Down Expand Up @@ -94,33 +94,33 @@ defmodule Mongo.Messages do
@doc """
Decodes a reply message from the response
"""
def decode_reply(<<flags::int32, cursor_id::int64, from::int32, num::int32, rest::binary>>) do
def decode_reply(<<flags::int32(), cursor_id::int64(), from::int32(), num::int32(), rest::binary>>) do
op_reply(flags: flags, cursor_id: cursor_id, from: from, num: num, docs: BSON.Decoder.documents(rest))
end

def decode_msg(<<flags::int32, rest::binary>>) do
def decode_msg(<<flags::int32(), rest::binary>>) do
op_msg(flags: flags, sections: decode_sections(rest))
end

def decode_sections(binary), do: decode_sections(binary, [])
def decode_sections("", acc), do: Enum.reverse(acc)

def decode_sections(<<0x00::int8, payload::binary>>, acc) do
<<size::int32, _rest::binary>> = payload
def decode_sections(<<0x00::int8(), payload::binary>>, acc) do
<<size::int32(), _rest::binary>> = payload
<<doc::binary(size), rest::binary>> = payload

with {doc, ""} <- BSON.Decoder.document(doc) do
decode_sections(rest, [section(payload_type: 0, payload: payload(doc: doc)) | acc])
end
end

def decode_sections(<<0x01::int8, payload::binary>>, acc) do
<<size::int32, _rest::binary>> = payload
def decode_sections(<<0x01::int8(), payload::binary>>, acc) do
<<size::int32(), _rest::binary>> = payload
<<sequence::binary(size), rest::binary>> = payload
decode_sections(rest, [section(payload_type: 1, payload: payload(sequence: decode_sequence(sequence))) | acc])
end

def decode_sequence(<<size::int32, rest::binary>>) do
def decode_sequence(<<size::int32(), rest::binary>>) do
with {identifier, docs} <- cstring(rest) do
sequence(size: size, identifier: identifier, docs: BSON.Decoder.documents(docs))
end
Expand All @@ -144,23 +144,23 @@ defmodule Mongo.Messages do
end

defp encode_header(msg_header(length: length, request_id: request_id, response_to: response_to, op_code: op_code)) do
<<length::int32, request_id::int32, response_to::int32, op_code::int32>>
<<length::int32(), request_id::int32(), response_to::int32(), op_code::int32()>>
end

defp encode_op(op_query(flags: flags, coll: coll, num_skip: num_skip, num_return: num_return, query: query, select: select)) do
[<<blit_flags(:query, flags)::int32>>, coll, <<0x00, num_skip::int32, num_return::int32>>, BSON.Encoder.document(query), select]
[<<blit_flags(:query, flags)::int32()>>, coll, <<0x00, num_skip::int32(), num_return::int32()>>, BSON.Encoder.document(query), select]
end

defp encode_op(op_msg(flags: flags, sections: sections)) do
[<<blit_flags(:msg, flags)::int32>> | encode_sections(sections)]
[<<blit_flags(:msg, flags)::int32()>> | encode_sections(sections)]
end

defp encode_sections(sections) do
Enum.map(sections, fn section -> encode_section(section) end)
end

defp encode_section(section(payload_type: t, payload: payload)) do
[<<t::int8>> | encode_payload(payload)]
[<<t::int8()>> | encode_payload(payload)]
end

defp encode_payload(payload(doc: doc, sequence: nil)) do
Expand All @@ -170,7 +170,7 @@ defmodule Mongo.Messages do
defp encode_payload(payload(doc: nil, sequence: sequence(identifier: identifier, docs: docs))) do
iodata = [identifier, <<0x00>> | Enum.map(docs, fn doc -> BSON.Encoder.encode(doc) end)]
size = IO.iodata_length(iodata) + 4
[<<size::int32>> | iodata]
[<<size::int32()>> | iodata]
end

defp blit_flags(op, flags) when is_list(flags) do
Expand Down
16 changes: 13 additions & 3 deletions lib/mongo/monitor.ex
Expand Up @@ -178,7 +178,7 @@ defmodule Mongo.Monitor do
end

error ->
Logger.warn("Unable to update server description because of #{inspect(error)}")
warning("Unable to update server description because of #{inspect(error)}")
state
end
end
Expand All @@ -195,7 +195,7 @@ defmodule Mongo.Monitor do
%{state | round_trip_time: round_trip_time}

error ->
Logger.warn("Unable to round trip time because of #{inspect(error)}")
warning("Unable to round trip time because of #{inspect(error)}")
state
end
end
Expand All @@ -212,7 +212,7 @@ defmodule Mongo.Monitor do
%{state | mode: :streaming_mode, streaming_pid: pid, heartbeat_frequency_ms: 10_000}

error ->
Logger.warn("Unable to start the streaming hello monitor, because of #{inspect(error)}")
warning("Unable to start the streaming hello monitor, because of #{inspect(error)}")
state
end
end
Expand Down Expand Up @@ -284,4 +284,14 @@ defmodule Mongo.Monitor do
def info(message) do
Logger.info(IO.ANSI.format([:light_magenta, :bright, message]))
end

if macro_exported?(Logger, :warning, 2) do
defp warning(message) do
Logger.warning(message)
end
else
defp warning(message) do
Logger.warn(message)
end
end
end
2 changes: 1 addition & 1 deletion lib/mongo/url_parser.ex
Expand Up @@ -137,7 +137,7 @@ defmodule Mongo.UrlParser do

with url_char <- String.to_charlist(url),
{:ok, {_, _, _, _, _, srv_record}} <-
:inet_res.getbyname('_mongodb._tcp.' ++ url_char, :srv),
:inet_res.getbyname(~c"_mongodb._tcp." ++ url_char, :srv),
{:ok, host} <- get_host_srv(srv_record),
{:ok, {_, _, _, _, _, txt_record}} <- :inet_res.getbyname(url_char, :txt),
txt <- "#{orig_options}&#{txt_record}&ssl=true" do
Expand Down
8 changes: 2 additions & 6 deletions mix.exs
Expand Up @@ -23,21 +23,17 @@ defmodule Mongodb.Mixfile do

def application do
[
applications: applications(Mix.env()),
env: [],
extra_applications: [:crypto, :ssl, :eex],
extra_applications: [:logger, :crypto, :ssl],
mod: {Mongo.App, []}
]
end

def applications(:test), do: [:logger, :connection, :db_connection]
def applications(_), do: [:logger, :connection, :db_connection]

defp deps do
[
{:telemetry, "~> 1.0"},
{:db_connection, "~> 2.4.1"},
{:decimal, "~> 2.0"},
{:decimal, "~> 2.1.1"},
{:patch, "~> 0.12.0", only: [:dev, :test]},
{:jason, "~> 1.3", only: [:dev, :test]},
{:credo, "~> 1.6.1", only: [:dev, :test], runtime: false},
Expand Down
2 changes: 1 addition & 1 deletion mix.lock
Expand Up @@ -5,7 +5,7 @@
"connection": {:hex, :connection, "1.1.0", "ff2a49c4b75b6fb3e674bfc5536451607270aac754ffd1bdfe175abe4a6d7a68", [:mix], [], "hexpm", "722c1eb0a418fbe91ba7bd59a47e28008a189d47e37e0e7bb85585a016b2869c"},
"credo": {:hex, :credo, "1.6.4", "ddd474afb6e8c240313f3a7b0d025cc3213f0d171879429bf8535d7021d9ad78", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:file_system, "~> 0.2.8", [hex: :file_system, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "c28f910b61e1ff829bffa056ef7293a8db50e87f2c57a9b5c3f57eee124536b7"},
"db_connection": {:hex, :db_connection, "2.4.1", "6411f6e23f1a8b68a82fa3a36366d4881f21f47fc79a9efb8c615e62050219da", [:mix], [{:connection, "~> 1.0", [hex: :connection, repo: "hexpm", optional: false]}, {:telemetry, "~> 0.4 or ~> 1.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "ea36d226ec5999781a9a8ad64e5d8c4454ecedc7a4d643e4832bf08efca01f00"},
"decimal": {:hex, :decimal, "2.0.0", "a78296e617b0f5dd4c6caf57c714431347912ffb1d0842e998e9792b5642d697", [:mix], [], "hexpm", "34666e9c55dea81013e77d9d87370fe6cb6291d1ef32f46a1600230b1d44f577"},
"decimal": {:hex, :decimal, "2.1.1", "5611dca5d4b2c3dd497dec8f68751f1f1a54755e8ed2a966c2633cf885973ad6", [:mix], [], "hexpm", "53cfe5f497ed0e7771ae1a475575603d77425099ba5faef9394932b35020ffcc"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"dialyxir": {:hex, :dialyxir, "0.5.1", "b331b091720fd93e878137add264bac4f644e1ddae07a70bf7062c7862c4b952", [:mix], [], "hexpm", "6c32a70ed5d452c6650916555b1f96c79af5fc4bf286997f8b15f213de786f73"},
"earmark": {:hex, :earmark, "1.4.15", "2c7f924bf495ec1f65bd144b355d0949a05a254d0ec561740308a54946a67888", [:mix], [{:earmark_parser, ">= 1.4.13", [hex: :earmark_parser, repo: "hexpm", optional: false]}], "hexpm", "3b1209b85bc9f3586f370f7c363f6533788fb4e51db23aa79565875e7f9999ee"},
Expand Down
2 changes: 1 addition & 1 deletion test/bson_test.exs
Expand Up @@ -112,7 +112,7 @@ defmodule BSONTest do
assert encode(@map_23) == @bin_23
assert encode(@map_24) == @bin_24
assert encode(@map_25) == @bin_25
assert encode(@map_26) == @bin_26
assert @map_26 |> encode() |> decode() == %{"age" => 27, "name" => "John"}
end

test "decode" do
Expand Down
2 changes: 1 addition & 1 deletion test/mongo/connection_test.exs
Expand Up @@ -69,7 +69,7 @@ defmodule Mongo.ConnectionTest do
end

defp connect_ssl do
assert {:ok, pid} = Mongo.start_link(hostname: "localhost", database: "mongodb_test", ssl: true, ssl_opts: [ciphers: ['AES256-GCM-SHA384'], versions: [:"tlsv1.2"]])
assert {:ok, pid} = Mongo.start_link(hostname: "localhost", database: "mongodb_test", ssl: true, ssl_opts: [ciphers: [~c"AES256-GCM-SHA384"], versions: [:"tlsv1.2"]])
pid
end

Expand Down
13 changes: 12 additions & 1 deletion test/mongo/cursor_test.exs
Expand Up @@ -38,7 +38,18 @@ defmodule Mongo.CursorTest do
# issue #35: Crash executing find function without enough permission
test "matching errors in the next function of the stream api", c do
assert {:error,
%Mongo.Error{__exception__: true, code: 2, error_labels: '', fail_command: false, host: nil, message: "unknown operator: $gth", resumable: false, retryable_reads: false, retryable_writes: false, not_writable_primary_or_recovering: false}} ==
%Mongo.Error{
__exception__: true,
code: 2,
error_labels: ~c"",
fail_command: false,
host: nil,
message: "unknown operator: $gth",
resumable: false,
retryable_reads: false,
retryable_writes: false,
not_writable_primary_or_recovering: false
}} ==
Mongo.find(c.pid, "test", _id: ["$gth": 1])
end
end

0 comments on commit f621a62

Please sign in to comment.