changed
CHANGELOG.md
|
@@ -1,5 +1,11 @@
|
1
1
|
# Changelog
|
2
2
|
|
3
|
+ ## v0.6.4 (2023-12-04)
|
4
|
+
|
5
|
+ * Let DBConnection rollback for failed commit or disconnect failed begin/rollback
|
6
|
+ * Trap exits from connect callback
|
7
|
+ * Handle duplicate column names in Table.Reader implementation
|
8
|
+
|
3
9
|
## v0.6.3 (2022-09-22)
|
4
10
|
|
5
11
|
* Print query statement in error log
|
changed
hex_metadata.config
|
@@ -1,7 +1,36 @@
|
1
|
- {<<"app">>,<<"myxql">>}.
|
2
|
- {<<"build_tools">>,[<<"mix">>]}.
|
1
|
+ {<<"links">>,[{<<"GitHub">>,<<"https://github.com/elixir-ecto/myxql">>}]}.
|
2
|
+ {<<"name">>,<<"myxql">>}.
|
3
|
+ {<<"version">>,<<"0.6.4">>}.
|
3
4
|
{<<"description">>,<<"MySQL 5.5+ driver for Elixir">>}.
|
4
5
|
{<<"elixir">>,<<"~> 1.7">>}.
|
6
|
+ {<<"app">>,<<"myxql">>}.
|
7
|
+ {<<"licenses">>,[<<"Apache-2.0">>]}.
|
8
|
+ {<<"requirements">>,
|
9
|
+ [[{<<"name">>,<<"db_connection">>},
|
10
|
+ {<<"app">>,<<"db_connection">>},
|
11
|
+ {<<"optional">>,false},
|
12
|
+ {<<"requirement">>,<<"~> 2.4.1 or ~> 2.5">>},
|
13
|
+ {<<"repository">>,<<"hexpm">>}],
|
14
|
+ [{<<"name">>,<<"decimal">>},
|
15
|
+ {<<"app">>,<<"decimal">>},
|
16
|
+ {<<"optional">>,false},
|
17
|
+ {<<"requirement">>,<<"~> 1.6 or ~> 2.0">>},
|
18
|
+ {<<"repository">>,<<"hexpm">>}],
|
19
|
+ [{<<"name">>,<<"jason">>},
|
20
|
+ {<<"app">>,<<"jason">>},
|
21
|
+ {<<"optional">>,true},
|
22
|
+ {<<"requirement">>,<<"~> 1.0">>},
|
23
|
+ {<<"repository">>,<<"hexpm">>}],
|
24
|
+ [{<<"name">>,<<"geo">>},
|
25
|
+ {<<"app">>,<<"geo">>},
|
26
|
+ {<<"optional">>,true},
|
27
|
+ {<<"requirement">>,<<"~> 3.4">>},
|
28
|
+ {<<"repository">>,<<"hexpm">>}],
|
29
|
+ [{<<"name">>,<<"table">>},
|
30
|
+ {<<"app">>,<<"table">>},
|
31
|
+ {<<"optional">>,true},
|
32
|
+ {<<"requirement">>,<<"~> 0.1.0">>},
|
33
|
+ {<<"repository">>,<<"hexpm">>}]]}.
|
5
34
|
{<<"files">>,
|
6
35
|
[<<"lib">>,<<"lib/myxql">>,<<"lib/myxql/client.ex">>,
|
7
36
|
<<"lib/myxql/protocol.ex">>,<<"lib/myxql/error.ex">>,
|
|
@@ -13,33 +42,4 @@
|
13
42
|
<<"lib/myxql/connection.ex">>,<<"lib/myxql/text_query.ex">>,
|
14
43
|
<<"lib/myxql.ex">>,<<".formatter.exs">>,<<"mix.exs">>,<<"README.md">>,
|
15
44
|
<<"LICENSE.md">>,<<"CHANGELOG.md">>]}.
|
16
|
- {<<"licenses">>,[<<"Apache-2.0">>]}.
|
17
|
- {<<"links">>,[{<<"GitHub">>,<<"https://github.com/elixir-ecto/myxql">>}]}.
|
18
|
- {<<"name">>,<<"myxql">>}.
|
19
|
- {<<"requirements">>,
|
20
|
- [[{<<"app">>,<<"db_connection">>},
|
21
|
- {<<"name">>,<<"db_connection">>},
|
22
|
- {<<"optional">>,false},
|
23
|
- {<<"repository">>,<<"hexpm">>},
|
24
|
- {<<"requirement">>,<<"~> 2.4.1 or ~> 2.5">>}],
|
25
|
- [{<<"app">>,<<"decimal">>},
|
26
|
- {<<"name">>,<<"decimal">>},
|
27
|
- {<<"optional">>,false},
|
28
|
- {<<"repository">>,<<"hexpm">>},
|
29
|
- {<<"requirement">>,<<"~> 1.6 or ~> 2.0">>}],
|
30
|
- [{<<"app">>,<<"jason">>},
|
31
|
- {<<"name">>,<<"jason">>},
|
32
|
- {<<"optional">>,true},
|
33
|
- {<<"repository">>,<<"hexpm">>},
|
34
|
- {<<"requirement">>,<<"~> 1.0">>}],
|
35
|
- [{<<"app">>,<<"geo">>},
|
36
|
- {<<"name">>,<<"geo">>},
|
37
|
- {<<"optional">>,true},
|
38
|
- {<<"repository">>,<<"hexpm">>},
|
39
|
- {<<"requirement">>,<<"~> 3.4">>}],
|
40
|
- [{<<"app">>,<<"table">>},
|
41
|
- {<<"name">>,<<"table">>},
|
42
|
- {<<"optional">>,true},
|
43
|
- {<<"repository">>,<<"hexpm">>},
|
44
|
- {<<"requirement">>,<<"~> 0.1.0">>}]]}.
|
45
|
- {<<"version">>,<<"0.6.3">>}.
|
45
|
+ {<<"build_tools">>,[<<"mix">>]}.
|
changed
lib/myxql/connection.ex
|
@@ -18,6 +18,9 @@ defmodule MyXQL.Connection do
|
18
18
|
|
19
19
|
@impl true
|
20
20
|
def connect(opts) do
|
21
|
+ # Trap exits so that DBConnection calls `disconnect` on unexpected shutdowns
|
22
|
+ Process.flag(:trap_exit, true)
|
23
|
+
|
21
24
|
prepare = Keyword.get(opts, :prepare, :named)
|
22
25
|
ping_timeout = Keyword.get(opts, :ping_timeout, 15_000)
|
23
26
|
config = Client.Config.new(opts)
|
|
@@ -413,7 +416,7 @@ defmodule MyXQL.Connection do
|
413
416
|
|
414
417
|
defp format_reason(reason) do
|
415
418
|
case :ssl.format_error(reason) do
|
416
|
- 'Unexpected error' ++ _ ->
|
419
|
+ ~c"Unexpected error" ++ _ ->
|
417
420
|
inspect(reason)
|
418
421
|
|
419
422
|
message ->
|
|
@@ -438,7 +441,12 @@ defmodule MyXQL.Connection do
|
438
441
|
{:ok, result, state}
|
439
442
|
|
440
443
|
other ->
|
441
|
- result(other, statement, state)
|
444
|
+ # We convert {:error, exception, state} to {:error, state}
|
445
|
+ # so that DBConnection will disconnect during handle_begin/handle_rollback
|
446
|
+ # and will attempt to rollback during handle_commit
|
447
|
+ with {:error, _exception, state} <- result(other, statement, state) do
|
448
|
+ {:error, state}
|
449
|
+ end
|
442
450
|
end
|
443
451
|
end
|
changed
lib/myxql/protocol/server_error_codes.ex
|
@@ -1,7 +1,15 @@
|
1
1
|
defmodule MyXQL.Protocol.ServerErrorCodes do
|
2
2
|
@moduledoc false
|
3
3
|
|
4
|
- codes = [
|
4
|
+ # TODO: remove when we require Elixir v1.10+
|
5
|
+ codes_from_config =
|
6
|
+ if Version.match?(System.version(), ">= 1.10.0") do
|
7
|
+ Application.compile_env(:myxql, :extra_error_codes, [])
|
8
|
+ else
|
9
|
+ apply(Application, :get_env, [:myxql, :extra_error_codes, []])
|
10
|
+ end
|
11
|
+
|
12
|
+ default_codes = [
|
5
13
|
{1005, :ER_CANT_CREATE_TABLE},
|
6
14
|
{1006, :ER_CANT_CREATE_DB},
|
7
15
|
{1007, :ER_DB_CREATE_EXISTS},
|
|
@@ -23,8 +31,7 @@ defmodule MyXQL.Protocol.ServerErrorCodes do
|
23
31
|
{1836, :ER_READ_ONLY_MODE}
|
24
32
|
]
|
25
33
|
|
26
|
- # TODO: use Application.compile_env/3 when we require Elixir v1.10
|
27
|
- codes = codes ++ Application.get_env(:myxql, :extra_error_codes, [])
|
34
|
+ codes = default_codes ++ codes_from_config
|
28
35
|
|
29
36
|
for {code, name} <- Enum.uniq(codes) do
|
30
37
|
def name_to_code(unquote(name)), do: unquote(code)
|
changed
lib/myxql/result.ex
|
@@ -48,7 +48,17 @@ if Code.ensure_loaded?(Table.Reader) do
|
48
48
|
end
|
49
49
|
|
50
50
|
def init(result) do
|
51
|
- {:rows, %{columns: result.columns, count: result.num_rows}, result.rows}
|
51
|
+ {columns, _} =
|
52
|
+ Enum.map_reduce(result.columns, %{}, fn column, counts ->
|
53
|
+ counts = Map.update(counts, column, 1, &(&1 + 1))
|
54
|
+
|
55
|
+ case counts[column] do
|
56
|
+ 1 -> {column, counts}
|
57
|
+ n -> {"#{column}_#{n}", counts}
|
58
|
+ end
|
59
|
+ end)
|
60
|
+
|
61
|
+ {:rows, %{columns: columns, count: result.num_rows}, result.rows}
|
52
62
|
end
|
53
63
|
end
|
54
64
|
end
|
changed
mix.exs
|
@@ -1,7 +1,7 @@
|
1
1
|
defmodule MyXQL.MixProject do
|
2
2
|
use Mix.Project
|
3
3
|
|
4
|
- @version "0.6.3"
|
4
|
+ @version "0.6.4"
|
5
5
|
@source_url "https://github.com/elixir-ecto/myxql"
|
6
6
|
|
7
7
|
def project() do
|