Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add json column support mysql(5.7~) #201

Merged
merged 11 commits into from
Nov 8, 2017
14 changes: 7 additions & 7 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,14 @@ notifications:
sudo: false
env:
matrix:
- DB=mariadb:10.1
- DB=mariadb:10.2
- DB=mariadb:10.3
- DB=mysql:8.0
- DB=mysql:5.7
- DB=mysql:5.6
- DB=mariadb:10.1 JSON_SUPPORT=false
- DB=mariadb:10.2 JSON_SUPPORT=false
- DB=mariadb:10.3 JSON_SUPPORT=false
- DB=mysql:8.0 JSON_SUPPORT=true
- DB=mysql:5.7 JSON_SUPPORT=true
- DB=mysql:5.6 JSON_SUPPORT=false
before_install:
- sudo service mysql stop
- docker pull $DB || true
- docker run --name mariadb -p 3306:3306 -e MYSQL_ALLOW_EMPTY_PASSWORD=1 -d $DB
script: "mix test --cover"
script: "JSON_SUPPORT=$JSON_SUPPORT mix test --cover"
10 changes: 10 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,3 +36,13 @@ After you are done, run `mix deps.get` in your shell to fetch and compile Mariae

Important configuration, which depends on used charset for support unicode chars, see `:binary_as`
in `Mariaex.start_link/1`

### JSON library

As default, [Poison](https://github.com/devinus/poison) is used for JSON library in mariaex to support JSON column.

If you want to use another library, please set `config.exs` like below.

```elixir
config :mariaex, json_library: SomeLibrary
```
18 changes: 10 additions & 8 deletions lib/mariaex/messages.ex
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ defmodule Mariaex.Messages do
field_type_blob: 0xfc,
field_type_var_string: 0xfd,
field_type_string: 0xfe],
json:
[field_type_json: 0xf5],
null:
[field_type_null: 0x06]
]
Expand Down Expand Up @@ -229,32 +231,32 @@ defmodule Mariaex.Messages do
do: {nil, rest}

def decode_bin_rows(<< len :: size(24)-little-integer, seqnum :: size(8)-integer, body :: size(len)-binary, rest :: binary>>,
fields, nullbin_size, rows, datetime) do
fields, nullbin_size, rows, datetime, json_library) do
case body do
<<0 :: 8, nullbin::size(nullbin_size)-little-unit(8), values :: binary>> ->
row = Mariaex.RowParser.decode_bin_rows(values, fields, nullbin, datetime)
decode_bin_rows(rest, fields, nullbin_size, [row | rows], datetime)
row = Mariaex.RowParser.decode_bin_rows(values, fields, nullbin, datetime, json_library)
decode_bin_rows(rest, fields, nullbin_size, [row | rows], datetime, json_library)
body ->
msg = decode_msg(body, :bin_rows)
{:ok, packet(size: len, seqnum: seqnum, msg: msg, body: body), rows, rest}
end
end
def decode_bin_rows(<<rest :: binary>>, _fields, _nullbin_size, rows, _datetime) do
def decode_bin_rows(<<rest :: binary>>, _fields, _nullbin_size, rows, _datetime, _json_library) do
{:more, rows, rest}
end

def decode_text_rows(<< len :: size(24)-little-integer, seqnum :: size(8)-integer, body :: size(len)-binary, rest :: binary>>,
fields, rows, datetime) do
fields, rows, datetime, json_library) do
case body do
<< 254 :: 8, _ :: binary >> = body when byte_size(body) < 9 ->
msg = decode_msg(body, :text_rows)
{:ok, packet(size: len, seqnum: seqnum, msg: msg, body: body), rows, rest}
body ->
row = Mariaex.RowParser.decode_text_rows(body, fields, datetime)
decode_text_rows(rest, fields, [row | rows], datetime)
row = Mariaex.RowParser.decode_text_rows(body, fields, datetime, json_library)
decode_text_rows(rest, fields, [row | rows], datetime, json_library)
end
end
def decode_text_rows(<<rest :: binary>>, _fields, rows, _datetime) do
def decode_text_rows(<<rest :: binary>>, _fields, rows, _datetime, _json_library) do
{:more, rows, rest}
end

Expand Down
11 changes: 7 additions & 4 deletions lib/mariaex/protocol.ex
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ defmodule Mariaex.Protocol do
cursors: %{},
seqnum: 0,
datetime: :structs,
json_library: Poison,
ssl_conn_state: :undefined # :undefined | :not_used | :ssl_handshake | :connected

@doc """
Expand All @@ -76,6 +77,7 @@ defmodule Mariaex.Protocol do
connect_opts = [host, opts[:port], opts[:socket_options], opts[:timeout]]
binary_as = opts[:binary_as] || :field_type_var_string
datetime = opts[:datetime] || :structs
json_library = Application.get_env(:mariaex, :json_library, Poison)

case apply(sock_mod, :connect, connect_opts) do
{:ok, sock} ->
Expand All @@ -88,6 +90,7 @@ defmodule Mariaex.Protocol do
lru_cache: reset_lru_cache(opts[:cache_size]),
timeout: opts[:timeout],
datetime: datetime,
json_library: json_library,
opts: opts}
handshake_recv(s, %{opts: opts})
{:error, reason} ->
Expand Down Expand Up @@ -531,8 +534,8 @@ defmodule Mariaex.Protocol do
end
end

defp text_row_decode(%{datetime: datetime} = s, fields, rows, buffer) do
case decode_text_rows(buffer, fields, rows, datetime) do
defp text_row_decode(%{datetime: datetime, json_library: json_library} = s, fields, rows, buffer) do
case decode_text_rows(buffer, fields, rows, datetime, json_library) do
{:ok, packet, rows, rest} ->
{:ok, packet, rows, %{s | buffer: rest}}
{:more, rows, rest} ->
Expand Down Expand Up @@ -638,8 +641,8 @@ defmodule Mariaex.Protocol do
end
end

defp binary_row_decode(%{datetime: datetime} = s, fields, nullbin_size, rows, buffer) do
case decode_bin_rows(buffer, fields, nullbin_size, rows, datetime) do
defp binary_row_decode(%{datetime: datetime, json_library: json_library} = s, fields, nullbin_size, rows, buffer) do
case decode_bin_rows(buffer, fields, nullbin_size, rows, datetime, json_library) do
{:ok, packet, rows, rest} ->
{:ok, packet, rows, %{s | buffer: rest}}
{:more, rows, rest} ->
Expand Down
Loading