Skip to content

Commit 96e7d6a

Browse files
committed
fix: this fixes the exception when using unknown atoms as compressor options (#294)
1 parent ab2c247 commit 96e7d6a

File tree

3 files changed

+42
-18
lines changed

3 files changed

+42
-18
lines changed

lib/mongo/compressor.ex

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,39 @@ defmodule Mongo.Compressor do
44
@zlib_compressor_id 2
55
@zstd_module Enum.find([:zstd, :ezstd], &Code.ensure_loaded?/1)
66

7+
if @zstd_module do
8+
@support_compressors ["zstd", "zlib"]
9+
else
10+
@support_compressors ["zlib"]
11+
end
12+
713
if @zstd_module do
814
@zstd_compressor_id 3
915
end
1016

17+
def map_compressors(nil) do
18+
[]
19+
end
20+
21+
def map_compressors(compressors) do
22+
compressors
23+
|> Enum.filter(fn compressor -> compressor in @support_compressors end)
24+
|> Enum.map(fn compressor -> compressor_to_atom(compressor) end)
25+
end
26+
27+
def compressor_to_atom("zstd") do
28+
:zstd
29+
end
30+
31+
def compressor_to_atom("zlib") do
32+
:zlib
33+
end
34+
1135
def zstd_available?, do: not is_nil(@zstd_module)
1236

13-
def compressors, do: if(zstd_available?(), do: ["zstd", "zlib"], else: ["zlib"])
37+
def compressors() do
38+
@support_compressors
39+
end
1440

1541
def compress(binary, :zlib) do
1642
{@zlib_compressor_id, :zlib.compress(binary)}

lib/mongo/server_description.ex

Lines changed: 2 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ defmodule Mongo.ServerDescription do
1010
@type type :: :standalone | :mongos | :possible_primary | :rs_primary | :rs_secondary | :rs_arbiter | :rs_other | :rs_ghost | :unknown
1111

1212
@type compressor_types :: :zlib | :zstd
13-
@support_compressors Compressor.compressors()
1413

1514
@type t :: %{
1615
address: String.t() | nil,
@@ -110,7 +109,7 @@ defmodule Mongo.ServerDescription do
110109
max_bson_object_size: hello_response["maxBsonObjectSize"] || 16_777_216,
111110
max_message_size_bytes: hello_response["maxMessageSizeBytes"] || 48_000_000,
112111
max_write_batch_size: hello_response["maxWriteBatchSize"] || 100_000,
113-
compression: map_compressors(hello_response["compression"]),
112+
compression: Compressor.map_compressors(hello_response["compression"]),
114113
read_only: hello_response["readOnly"] || false,
115114
logical_session_timeout: hello_response["logicalSessionTimeoutMinutes"] || 30,
116115
supports_retryable_writes: supports_retryable_writes,
@@ -143,24 +142,14 @@ defmodule Mongo.ServerDescription do
143142
max_bson_object_size: hello_response["maxBsonObjectSize"] || 16_777_216,
144143
max_message_size_bytes: hello_response["maxMessageSizeBytes"] || 48_000_000,
145144
max_write_batch_size: hello_response["maxWriteBatchSize"] || 100_000,
146-
compression: map_compressors(hello_response["compression"]),
145+
compression: Mongo.Compressor.map_compressors(hello_response["compression"]),
147146
read_only: hello_response["readOnly"] || false,
148147
logical_session_timeout: hello_response["logicalSessionTimeoutMinutes"] || 30,
149148
supports_retryable_writes: server_type != :standalone && max_wire_version >= @retryable_wire_version && hello_response["logicalSessionTimeoutMinutes"] != nil,
150149
replica?: replica?(server_type)
151150
}
152151
end
153152

154-
defp map_compressors(nil) do
155-
[]
156-
end
157-
158-
defp map_compressors(compressors) do
159-
compressors
160-
|> Enum.filter(fn compressor -> compressor in @support_compressors end)
161-
|> Enum.map(fn compressor -> String.to_existing_atom(compressor) end)
162-
end
163-
164153
# see https://github.com/mongodb/specifications/blob/master/source/server-discovery-and-monitoring/server-discovery-and-monitoring.rst#type
165154
defp determine_server_type(%{"ok" => n}) when n != 1, do: :unknown
166155
defp determine_server_type(%{"msg" => "isdbgrid"}), do: :mongos
@@ -178,10 +167,6 @@ defmodule Mongo.ServerDescription do
178167

179168
defp determine_server_type(_), do: :standalone
180169

181-
def support_compressors() do
182-
Enum.map(@support_compressors, &String.to_existing_atom/1)
183-
end
184-
185170
defp replica?(server_type) do
186171
server_type in [:rs_primary, :rs_secondary, :rs_arbiter, :rs_other, :rs_ghost]
187172
end

test/mongo/compression_test.exs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
defmodule Mongo.CompressorTest do
2+
use ExUnit.Case
3+
4+
alias Mongo.Compressor
5+
6+
test "the map_compressors should filter unsupported compressors" do
7+
assert [:zstd, :zlib] = Compressor.map_compressors(["snappy", "zstd", "zlib"])
8+
end
9+
10+
test "the map_compressors should return [] if no compressor is supported]" do
11+
assert [] = Compressor.map_compressors(["snappy"])
12+
end
13+
end

0 commit comments

Comments
 (0)