Viktor Söderqvist 10 лет назад
Родитель
Сommit
af487b9e06
5 измененных файлов с 38 добавлено и 34 удалено
  1. 6 8
      README.md
  2. 2 2
      src/mysql.app.src
  3. 16 11
      src/mysql.erl
  4. 3 2
      src/mysql_connection.erl
  5. 11 11
      test/mysql_tests.erl

+ 6 - 8
README.md

@@ -26,8 +26,8 @@ Synopsis
 Opts = [{host, "localhost"}, {user, "foo"}, {password, "hello"},
         {database, "test"}],
 
-%% This will probably be renamed to start_link/1
-{ok, Pid} = mysql:connect(Opts),
+%% Connect and link to the connection process.
+{ok, Pid} = mysql:start_link(Opts),
 
 %% A query returning results
 {ok, ColumnNames, Rows} = mysql:query(Pid, <<"SELECT * FROM mytable">>),
@@ -35,15 +35,13 @@ Opts = [{host, "localhost"}, {user, "foo"}, {password, "hello"},
 %% A query not returning any rows just returns ok.
 ok = mysql:query(Pid, "INSERT INTO mytable (foo, bar) VALUES (1, 42)"),
 
-%% Named prepared statements. Maybe the function should be execute/3
-%% instead of query/3.
+%% Named prepared statements.
 {ok, foo} = mysql:prepare(Pid, "SELECT * FROM mytable WHERE id=?", foo),
-{ok, Columns, Rows} = mysql:query(Pid, foo, [42]),
+{ok, Columns, Rows} = mysql:execute(Pid, foo, [42]),
 
-%% Unnamed prepared statements. The function query/3 will maybe be
-%% renamed to execute/3.
+%% Unnamed prepared statements.
 {ok, StmtId} = mysql:prepare(Pid, "SELECT * FROM mytable WHERE id=?"),
-{ok, Columns, Rows} = mysql:query(Pid, StmtId, [42]).
+{ok, Columns, Rows} = mysql:execute(Pid, StmtId, [42]).
 
 %% Separate calls to fetch more info about the last query
 LastInsertId = mysql:insert_id(Pid),

+ 2 - 2
src/mysql.app.src

@@ -15,7 +15,7 @@
 %% along with this program. If not, see <https://www.gnu.org/licenses/>.
 
 {application, mysql, [
-    {description, "MySQL/OTP - Erlang MySQL driver"},
-    {vsn, "0.0.2"},
+    {description, "MySQL/OTP - Erlang MySQL client"},
+    {vsn, "0.0.3"},
     {modules, []}
 ]}.

+ 16 - 11
src/mysql.erl

@@ -14,25 +14,30 @@
 %% You should have received a copy of the GNU General Public License
 %% along with this program. If not, see <https://www.gnu.org/licenses/>.
 
-%% @doc MySQL/OTP
+%% @doc MySQL/OTP. FIXME: Documentation of value representation, examples
+%% and more.
+%%
+%% This documentation is written with `edoc' as part of the source code and thus
+%% is covered by GPL 3 or later. See the LICENSE file or find GPL 3 on
+%% <a href="http://www.gnu.org/licenses/">http://www.gnu.org/licenses/</a>.
 -module(mysql).
 
--export([connect/1, disconnect/1, query/2, query/3, prepare/2, warning_count/1,
+-export([start_link/1, query/2, execute/3, prepare/2, warning_count/1,
          affected_rows/1, insert_id/1]).
 
 %% MySQL error with the codes and message returned from the server.
 -type reason() :: {Code :: integer(), SQLState :: binary(),
                    Message :: binary()}.
 
--spec connect(list()) -> {ok, pid()} | ignore | {error, term()}.
-connect(Opts) ->
+%% @doc Starts a connection process and connects to a database. To disconnect
+%% do `exit(Pid, normal)'.
+-spec start_link(Options) -> {ok, pid()} | ignore | {error, term()}
+    when Options :: [Option],
+         Option :: {host, iodata()} | {port, integer()} | {user, iodata()} |
+                   {password, iodata()} | {database, iodata()}.
+start_link(Opts) ->
     gen_server:start_link(mysql_connection, Opts, []).
 
--spec disconnect(pid()) -> ok.
-disconnect(Conn) ->
-    exit(Conn, normal),
-    ok.
-
 -spec query(Conn, Query) -> ok | {ok, Fields, Rows} | {error, Reason}
     when Conn :: pid(),
          Query :: iodata(),
@@ -43,8 +48,8 @@ query(Conn, Query) ->
     gen_server:call(Conn, {query, Query}).
 
 %% @doc Executes a prepared statement.
-query(Conn, StatementId, Args) ->
-    gen_server:call(Conn, {query, StatementId, Args}).
+execute(Conn, StatementId, Args) ->
+    gen_server:call(Conn, {execute, StatementId, Args}).
 
 -spec prepare(Conn :: pid(), Query :: iodata()) ->
     {ok, StatementId :: integer()} | {error, Reason :: reason()}.

+ 3 - 2
src/mysql_connection.erl

@@ -82,8 +82,9 @@ handle_call({query, Query}, _From, State) when is_binary(Query);
             Names = [Def#column_definition.name || Def <- ColDefs],
             {reply, {ok, Names, Rows}, State1}
     end;
-handle_call({query, Stmt, Args}, _From, State) when is_integer(Stmt);
-                                                    is_atom(Stmt) ->
+handle_call({execute, Stmt, Args}, _From, State) when is_integer(Stmt);
+                                                      is_atom(Stmt) ->
+    %% TODO: Return {error, not_prepared} instead of crashing if not found.
     StmtRec = dict:fetch(Stmt, State#state.stmts),
     #state{socket = Socket, timeout = Timeout} = State,
     SendFun = fun (Data) -> gen_tcp:send(Socket, Data) end,

+ 11 - 11
test/mysql_tests.erl

@@ -35,13 +35,13 @@
                           ") ENGINE=InnoDB">>).
 
 connect_test() ->
-    {ok, Pid} = mysql:connect([{user, ?user}, {password, ?password}]),
-    ?assertEqual(ok, mysql:disconnect(Pid)).
+    {ok, Pid} = mysql:start_link([{user, ?user}, {password, ?password}]),
+    exit(Pid, normal).
 
 query_test_() ->
     {setup,
      fun () ->
-         {ok, Pid} = mysql:connect([{user, ?user}, {password, ?password}]),
+         {ok, Pid} = mysql:start_link([{user, ?user}, {password, ?password}]),
          ok = mysql:query(Pid, <<"DROP DATABASE IF EXISTS otptest">>),
          ok = mysql:query(Pid, <<"CREATE DATABASE otptest">>),
          ok = mysql:query(Pid, <<"USE otptest">>),
@@ -49,7 +49,7 @@ query_test_() ->
      end,
      fun (Pid) ->
          ok = mysql:query(Pid, <<"DROP DATABASE otptest">>),
-         mysql:disconnect(Pid)
+         exit(Pid, normal)
      end,
      {with, [fun basic_queries/1,
              fun text_protocol/1,
@@ -105,16 +105,16 @@ binary_protocol(Pid) ->
     {ok, Ins} = mysql:prepare(Pid, <<"INSERT INTO t (bl, f, dc, ti, ts, da, c)"
                                      " VALUES (?, ?, ?, ?, ?, ?, ?)">>),
 
-    ok = mysql:query(Pid, Ins, [<<"blob">>, 3.14, <<"3.14">>,
-                                {time, {0, 22, 11}}, 
-                                {{2014, 11, 03}, {0, 22, 24}},
-                                {2014, 11, 03}, null]),
+    ok = mysql:execute(Pid, Ins, [<<"blob">>, 3.14, <<"3.14">>,
+                                  {time, {0, 22, 11}}, 
+                                  {{2014, 11, 03}, {0, 22, 24}},
+                                  {2014, 11, 03}, null]),
 
     %% TODO: Put the expected result in a macro to make sure they are identical
     %% for the text and the binary protocol tests.
 
     {ok, Stmt} = mysql:prepare(Pid, <<"SELECT * FROM t WHERE id=?">>),
-    {ok, Columns, Rows} = mysql:query(Pid, Stmt, [1]),
+    {ok, Columns, Rows} = mysql:execute(Pid, Stmt, [1]),
     ?assertEqual([<<"id">>, <<"bl">>, <<"tx">>, <<"f">>, <<"dc">>, <<"ti">>,
                   <<"ts">>, <<"da">>, <<"c">>], Columns),
     ?assertEqual([[1, <<"blob">>, <<>>, 3.14, <<"3.140">>,
@@ -164,14 +164,14 @@ float_rounding(Pid) ->
                 {2.12345111e23, 2.12345e23}, {-2.12345111e23, -2.12345e23}],
     lists:foreach(fun ({Input, Expected}) ->
                       %% Insert using binary protocol (sending it as a double)
-                      ok = mysql:query(Pid, Insert, [Input]),
+                      ok = mysql:execute(Pid, Insert, [Input]),
 
                       %% Text (plain query)
                       {ok, _, [[Value]]} = mysql:query(Pid, "SELECT f FROM f"),
                       ?assertEqual(Expected, Value),
 
                       %% Binary (prepared statement)
-                      {ok, _, [[BinValue]]} = mysql:query(Pid, Select, []),
+                      {ok, _, [[BinValue]]} = mysql:execute(Pid, Select, []),
                       ?assertEqual(Expected, BinValue),
 
                       %% cleanup before the next test