Skip to content

Commit 398d19e

Browse files
committed
Merge branch 'strip-encoding-code'
Conflicts: src/emysql.erl src/emysql_conn.erl src/emysql_util.erl
2 parents e166656 + ae469b9 commit 398d19e

File tree

3 files changed

+100
-172
lines changed

3 files changed

+100
-172
lines changed

src/emysql.erl

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -562,9 +562,10 @@ monitor_work(Connection, Timeout, Args) when is_record(Connection, emysql_connec
562562
%% it either dies, returns data or times out.
563563
Parent = self(),
564564
{Pid, Mref} = spawn_monitor(
565-
fun() ->
566-
Parent ! {self(), apply(fun emysql_conn:execute/3, Args)}
567-
end),
565+
fun() ->
566+
put(query_arguments, Args),
567+
Parent ! {self(), apply(fun emysql_conn:execute/3, Args)}
568+
end),
568569
receive
569570
{'DOWN', Mref, process, Pid, {_, closed}} ->
570571
%-% io:format("monitor_work: ~p DOWN/closed -> renew~n", [Pid]),

src/emysql_conn.erl

Lines changed: 64 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ set_encoding(Connection, Encoding) ->
4747

4848
execute(Connection, Query, []) when is_list(Query) ->
4949
%-% io:format("~p execute list: ~p using connection: ~p~n", [self(), iolist_to_binary(Query), Connection#emysql_connection.id]),
50-
Packet = <<?COM_QUERY, (emysql_util:to_binary(Query, Connection#emysql_connection.encoding))/binary>>,
50+
Packet = <<?COM_QUERY, (emysql_util:to_binary(Query))/binary>>,
5151
% Packet = <<?COM_QUERY, (iolist_to_binary(Query))/binary>>,
5252
emysql_tcp:send_and_recv_packet(Connection#emysql_connection.socket, Packet, 0);
5353

@@ -93,7 +93,7 @@ execute(Connection, StmtName, Args) when is_atom(StmtName), is_list(Args) ->
9393
prepare(Connection, Name, Statement) when is_atom(Name) ->
9494
prepare(Connection, atom_to_list(Name), Statement);
9595
prepare(Connection, Name, Statement) ->
96-
StatementBin = emysql_util:encode(Statement, binary, Connection#emysql_connection.encoding),
96+
StatementBin = emysql_util:encode(Statement, binary),
9797
Packet = <<?COM_QUERY, "PREPARE ", (list_to_binary(Name))/binary, " FROM ", StatementBin/binary>>, % todo: utf8?
9898
case emysql_tcp:send_and_recv_packet(Connection#emysql_connection.socket, Packet, 0) of
9999
OK when is_record(OK, ok_packet) ->
@@ -145,55 +145,67 @@ open_connection(#pool{pool_id=PoolId, host=Host, port=Port, user=User, password=
145145
%-% io:format("~p open connection: ... connect ... ~n", [self()]),
146146
case gen_tcp:connect(Host, Port, [binary, {packet, raw}, {active, false}]) of
147147
{ok, Sock} ->
148-
Greeting = case catch emysql_auth:do_handshake(Sock, User, Password) of
149-
{'EXIT', ExitReason} ->
150-
gen_tcp:close(Sock),
151-
exit(ExitReason);
152-
Greeting0 -> Greeting0
153-
end,
148+
#greeting {
149+
server_version = Version,
150+
thread_id = ThreadId,
151+
caps = Caps,
152+
language = Language
153+
} = handshake(Sock, User, Password),
154154
Connection = #emysql_connection{
155-
id = erlang:port_to_list(Sock),
156-
pool_id = PoolId,
157-
encoding = Encoding,
158-
socket = Sock,
159-
version = Greeting#greeting.server_version,
160-
thread_id = Greeting#greeting.thread_id,
161-
caps = Greeting#greeting.caps,
162-
language = Greeting#greeting.language
163-
},
164-
165-
%-% io:format("~p open connection: ... set db ...~n", [self()]),
166-
case set_database(Connection, Database) of
167-
ok -> ok;
168-
OK1 when is_record(OK1, ok_packet) ->
169-
%-% io:format("~p open connection: ... db set ok~n", [self()]),
170-
ok;
171-
Err1 when is_record(Err1, error_packet) ->
172-
%-% io:format("~p open connection: ... db set error~n", [self()]),
173-
gen_tcp:close(Sock),
174-
exit({failed_to_set_database, Err1#error_packet.msg})
175-
end,
176-
%-% io:format("~p open connection: ... set encoding ...: ~p~n", [self(), Encoding]),
177-
case set_encoding(Connection, Encoding) of
178-
OK2 when is_record(OK2, ok_packet) ->
179-
ok;
180-
Err2 when is_record(Err2, error_packet) ->
181-
gen_tcp:close(Sock),
182-
exit({failed_to_set_encoding, Err2#error_packet.msg})
183-
end,
184-
case emysql_conn_mgr:give_manager_control(Sock) of
185-
{error ,Reason} ->
186-
gen_tcp:close(Sock),
187-
exit({Reason,
188-
"Failed to find conn mgr when opening connection. Make sure crypto is started and emysql.app is in the Erlang path."});
189-
ok -> Connection
190-
end;
155+
id = erlang:port_to_list(Sock),
156+
pool_id = PoolId,
157+
encoding = Encoding,
158+
socket = Sock,
159+
version = Version,
160+
thread_id = ThreadId,
161+
caps = Caps,
162+
language = Language
163+
},
164+
%%-% io:format("~p open connection: ... set db ...~n", [self()]),
165+
ok = set_database_or_die(Connection, Database),
166+
ok = set_encoding_or_die(Connection, Encoding),
167+
ok = give_manager_control(Sock),
168+
Connection;
191169
{error, Reason} ->
192170
%-% io:format("~p open connection: ... ERROR ~p~n", [self(), Reason]),
193171
%-% io:format("~p open connection: ... exit with failed_to_connect_to_database~n", [self()]),
194172
exit({failed_to_connect_to_database, Reason})
195173
end.
196174

175+
handshake(Sock, User, Password) ->
176+
case catch emysql_auth:do_handshake(Sock, User, Password) of
177+
{'EXIT', ExitReason} ->
178+
gen_tcp:close(Sock),
179+
exit(ExitReason);
180+
#greeting{} = G -> G
181+
end.
182+
183+
give_manager_control(Socket) ->
184+
case emysql_conn_mgr:give_manager_control(Socket) of
185+
{error, Reason} ->
186+
gen_tcp:close(Socket),
187+
exit({Reason,
188+
"Failed to find conn mgr when opening connection. Make sure crypto is started and emysql.app is in the Erlang path."});
189+
ok -> ok
190+
end.
191+
192+
set_database_or_die(#emysql_connection { socket = Socket } = Connection, Database) ->
193+
case set_database(Connection, Database) of
194+
ok -> ok;
195+
OK1 when is_record(OK1, ok_packet) -> ok;
196+
Err1 when is_record(Err1, error_packet) ->
197+
gen_tcp:close(Socket),
198+
exit({failed_to_set_database, Err1#error_packet.msg})
199+
end.
200+
201+
set_encoding_or_die(#emysql_connection { socket = Socket } = Connection, Encoding) ->
202+
case set_encoding(Connection, Encoding) of
203+
OK2 when is_record(OK2, ok_packet) -> ok;
204+
Err2 when is_record(Err2, error_packet) ->
205+
gen_tcp:close(Socket),
206+
exit({failed_to_set_encoding, Err2#error_packet.msg})
207+
end.
208+
197209
reset_connection(Pools, Conn, StayLocked) ->
198210
%% if a process dies or times out while doing work
199211
%% the socket must be closed and the connection reset
@@ -209,9 +221,11 @@ reset_connection(Pools, Conn, StayLocked) ->
209221
{Pool, _} ->
210222
case catch open_connection(Pool) of
211223
#emysql_connection{} = NewConn when StayLocked == pass ->
212-
emysql_conn_mgr:replace_connection_as_available(Conn, NewConn);
224+
ok = emysql_conn_mgr:replace_connection_as_available(Conn, NewConn),
225+
NewConn;
213226
#emysql_connection{} = NewConn when StayLocked == keep ->
214-
emysql_conn_mgr:replace_connection_as_locked(Conn, NewConn);
227+
ok = emysql_conn_mgr:replace_connection_as_locked(Conn, NewConn),
228+
NewConn;
215229
{'EXIT', Reason} ->
216230
DeadConn = Conn#emysql_connection { alive = false },
217231
emysql_conn_mgr:replace_connection_as_available(Conn, DeadConn),
@@ -231,12 +245,12 @@ close_connection(Conn) ->
231245
%%--------------------------------------------------------------------
232246
set_params(_, _, [], Result) -> Result;
233247
set_params(Connection, Num, Values, _) ->
234-
Packet = set_params_packet(Num, Values, Connection#emysql_connection.encoding),
248+
Packet = set_params_packet(Num, Values),
235249
emysql_tcp:send_and_recv_packet(Connection#emysql_connection.socket, Packet, 0).
236250

237-
set_params_packet(NumStart, Values, Encoding) ->
238-
BinValues = [emysql_util:encode(Val, binary, Encoding) || Val <- Values],
239-
BinNums = [emysql_util:encode(Num, binary, Encoding) || Num <- lists:seq(NumStart, NumStart + length(Values) - 1)],
251+
set_params_packet(NumStart, Values) ->
252+
BinValues = [emysql_util:encode(Val, binary) || Val <- Values],
253+
BinNums = [emysql_util:encode(Num, binary) || Num <- lists:seq(NumStart, NumStart + length(Values) - 1)],
240254
BinPairs = lists:zip(BinNums, BinValues),
241255
Parts = [<<"@", NumBin/binary, "=", ValBin/binary>> || {NumBin, ValBin} <- BinPairs],
242256
Sets = list_to_binary(join(Parts, <<",">>)),

src/emysql_util.erl

Lines changed: 32 additions & 119 deletions
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,8 @@
2424
%% OTHER DEALINGS IN THE SOFTWARE.
2525
-module(emysql_util).
2626
-export([field_names/1, as_record/4, as_record/3, length_coded_binary/1, length_coded_string/1,
27-
null_terminated_string/2, asciz/1, bxor_binary/2, dualmap/3, hash/1,
27+
null_terminated_string/2, asciz/1, bxor_binary/2, dualmap/3, hash/1, to_binary/1,
2828
rnd/3, encode/1, encode/2, quote/1]).
29-
-compile(export_all).
3029

3130
-include("emysql.hrl").
3231

@@ -160,97 +159,51 @@ encode(Val) ->
160159

161160
%% @doc Encode a value so that it can be included safely in a MySQL query.
162161
%% @spec encode(term(), list | binary) -> string() | binary() | {error, Error}
163-
encode(Val, ReturnType) when is_atom(Val) ->
164-
encode(atom_to_list(Val), ReturnType, latin1); % todo: latin1?
165-
166-
encode(Val, ReturnType) ->
167-
encode(Val, ReturnType, latin1).
168-
169-
encode(null, list, _) ->
162+
encode(null, list) ->
170163
"null";
171-
172-
encode(undefined, list, _) ->
164+
encode(undefined, list) ->
173165
"null";
174-
175-
encode(null, binary, _) ->
166+
encode(null, binary) ->
176167
<<"null">>;
177-
178-
encode(undefined, binary, _) ->
168+
encode(undefined, binary) ->
179169
<<"null">>;
180-
181-
encode(Val, list, latin1) when is_binary(Val) ->
170+
encode(Val, list) when is_binary(Val) ->
182171
quote(binary_to_list(Val));
183-
184-
encode(Val, list, Encoding) when is_binary(Val) ->
185-
quote(unicode:characters_to_list(Val, Encoding));
186-
187-
encode(Val, binary, Encoding) when is_atom(Val) ->
188-
encode(atom_to_list(Val), binary, Encoding);
189-
190-
encode(Val, binary, latin1) when is_list(Val) ->
191-
list_to_binary(quote(Val));
192-
193-
encode(Val, binary, Encoding) when is_list(Val) ->
194-
unicode:characters_to_binary(quote(Val), Encoding, Encoding);
195-
196-
197-
encode(Val, binary, latin1) when is_binary(Val) ->
198-
%-% io:format("encode latin-1 in : ~s = ~w ~n", [Val, Val]),
199-
X = list_to_binary(quote(binary_to_list(Val))),
200-
%-% io:format("encode latin-1 out: ~s = ~w ~n", [X, X]),
201-
X;
202-
203-
encode(Val, binary, Encoding) when is_binary(Val) ->
204-
case unicode:characters_to_list(Val,Encoding) of
205-
{error,E1,E2} -> exit({invalid_utf8_binary, E1, E2});
206-
{incomplete,E1,E2} -> exit({invalid_utf8_binary, E1, E2});
207-
List ->
208-
unicode:characters_to_binary(quote(List),Encoding,Encoding)
209-
end;
210-
211-
encode(Val, list, _) when is_list(Val) ->
212-
%-% io:format("encode list in : ~s = ~w ~n", [Val, Val]),
213-
%-% io:format("encode list out: ~s = ~w ~n", [quote(Val), quote(Val)]),
172+
encode(Val, binary) when is_atom(Val) ->
173+
encode(atom_to_list(Val), binary);
174+
encode(Val, binary) when is_list(Val) ->
175+
list_to_binary(quote(Val));
176+
encode(Val, binary) when is_binary(Val) ->
177+
list_to_binary(quote(binary_to_list(Val)));
178+
encode(Val, list) when is_list(Val) ->
214179
quote(Val);
215-
216-
encode(Val, list, _) when is_integer(Val) ->
180+
encode(Val, list) when is_integer(Val) ->
217181
integer_to_list(Val);
218-
219-
encode(Val, binary, _) when is_integer(Val) ->
182+
encode(Val, binary) when is_integer(Val) ->
220183
list_to_binary(integer_to_list(Val));
221-
222-
encode(Val, list, _) when is_float(Val) ->
184+
encode(Val, list) when is_float(Val) ->
223185
[Res] = io_lib:format("~w", [Val]),
224186
Res;
225-
226-
encode(Val, binary, _) when is_float(Val) ->
187+
encode(Val, binary) when is_float(Val) ->
227188
iolist_to_binary(io_lib:format("~w", [Val]));
228-
229-
encode({datetime, Val}, ReturnType, Encoding) ->
230-
encode(Val, ReturnType, Encoding);
231-
232-
encode({date, Val}, ReturnType, Encoding) ->
233-
encode(Val, ReturnType, Encoding);
234-
235-
encode({time, Val}, ReturnType, Encoding) ->
236-
encode(Val, ReturnType, Encoding);
237-
238-
encode({{Year, Month, Day}, {Hour, Minute, Second}}, list, _) ->
189+
encode({datetime, Val}, ReturnType) ->
190+
encode(Val, ReturnType);
191+
encode({date, Val}, ReturnType) ->
192+
encode(Val, ReturnType);
193+
encode({time, Val}, ReturnType) ->
194+
encode(Val, ReturnType);
195+
encode({{Year, Month, Day}, {Hour, Minute, Second}}, list) ->
239196
Res = io_lib:format("'~4.4.0w-~2.2.0w-~2.2.0w ~2.2.0w:~2.2.0w:~2.2.0w'",
240197
[Year, Month, Day, Hour, Minute, Second]),
241198
lists:flatten(Res);
242-
243-
encode({{_Year, _Month, _Day}, {_Hour, _Minute, _Second}}=Val, binary, E) ->
244-
list_to_binary(encode(Val, list, E));
245-
246-
encode({Time1, Time2, Time3}, list, _) ->
199+
encode({{_Year, _Month, _Day}, {_Hour, _Minute, _Second}}=Val, binary) ->
200+
list_to_binary(encode(Val, list));
201+
encode({Time1, Time2, Time3}, list) ->
247202
Res = two_digits([Time1, Time2, Time3]),
248203
lists:flatten(Res);
249-
250-
encode({_Time1, _Time2, _Time3}=Val, binary, E) ->
251-
list_to_binary(encode(Val, list, E));
252-
253-
encode(Val, _, _) ->
204+
encode({_Time1, _Time2, _Time3}=Val, binary) ->
205+
list_to_binary(encode(Val, list));
206+
encode(Val, _) ->
254207
{error, {unrecognized_value, Val}}.
255208

256209
%% @private
@@ -273,23 +226,6 @@ two_digits(Num) ->
273226
quote(String) when is_list(String) ->
274227
[39 | lists:reverse([39 | quote_loop(String)])]. %% 39 is $'
275228

276-
quote(String, _) when is_list(String) ->
277-
quote(String);
278-
279-
quote(Any, Pool) when is_record(Pool,pool) ->
280-
quote(Any, Pool#pool.encoding);
281-
282-
quote(Bin, latin1) when is_binary(Bin) ->
283-
list_to_binary(quote(binary_to_list(Bin)));
284-
285-
quote(Bin, Encoding) when is_binary(Bin) ->
286-
case unicode:characters_to_list(Bin,Encoding) of
287-
{error,E1,E2} -> exit({invalid_utf8_binary, E1, E2});
288-
List ->
289-
unicode:characters_to_binary(quote(List),Encoding,Encoding)
290-
end.
291-
% note:quote is a codepoint-wise inspection (each is a number) that also works for Unicode.
292-
293229
%% @doc Make MySQL-safe backslash escapes before 10, 13, \, 26, 34, 39.
294230
%% @spec quote_loop(list()) -> list()
295231
%% @private
@@ -333,28 +269,5 @@ quote_loop([C | Rest], Acc) ->
333269
%% can be used to determine if data can be interpreted as UTF-8.
334270
%% Source: http://www.erlang.org/doc/apps/stdlib/unicode_usage.html
335271

336-
anybin_to_list(Bin) when is_binary(Bin) ->
337-
case unicode:characters_to_binary(Bin,utf8,utf8) of
338-
Bin -> unicode:characters_to_list(Bin);
339-
_ -> binary_to_list(Bin)
340-
end.
341-
342-
any_to_binary(L) when is_binary(L) ->
343-
L;
344-
any_to_binary(L) when is_list(L) ->
345-
case unicode:characters_to_binary(L) of
346-
{error,_,_} -> list_to_binary(L);
347-
B -> case unicode:characters_to_list(B,utf8) of
348-
L -> B;
349-
_ -> list_to_binary(L)
350-
end
351-
end.
352-
353-
to_binary(L,_) when is_binary(L) ->
354-
L;
355-
356-
to_binary(L,latin1) when is_list(L) ->
357-
list_to_binary(L);
358-
359-
to_binary(L,Encoding) when is_list(L) ->
360-
unicode:characters_to_binary(L,Encoding,Encoding).
272+
to_binary(L) when is_binary(L) -> L;
273+
to_binary(L) when is_list(L) -> list_to_binary(L).

0 commit comments

Comments
 (0)