Fix dialyzer warnings

This commit is contained in:
Heinz N. Gies
2015-09-21 18:24:50 +02:00
parent 16ffe88bbc
commit 69fe344610
3 changed files with 97 additions and 91 deletions

View File

@@ -1,7 +1,7 @@
{application, esqlite, {application, esqlite,
[ [
{description, "sqlite nif interface"}, {description, "sqlite nif interface"},
{vsn, "0.1.0"}, {vsn, "0.1.1"},
{modules, [esqlite3, esqlite3_nif]}, {modules, [esqlite3, esqlite3_nif]},
{registered, []}, {registered, []},
{applications, [ {applications, [

View File

@@ -8,9 +8,9 @@
%% Licensed under the Apache License, Version 2.0 (the "License"); %% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License. %% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at %% You may obtain a copy of the License at
%% %%
%% http://www.apache.org/licenses/LICENSE-2.0 %% http://www.apache.org/licenses/LICENSE-2.0
%% %%
%% Unless required by applicable law or agreed to in writing, software %% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS, %% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -21,14 +21,14 @@
-author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>"). -author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>").
%% higher-level export %% higher-level export
-export([open/1, open/2, -export([open/1, open/2,
exec/2, exec/3, exec/2, exec/3,
changes/1, changes/2, changes/1, changes/2,
insert/2, insert/2,
prepare/2, prepare/3, prepare/2, prepare/3,
step/1, step/2, step/1, step/2,
reset/1, reset/1,
bind/2, bind/3, bind/2, bind/3,
fetchone/1, fetchone/1,
fetchall/1, fetchall/1,
column_names/1, column_names/2, column_names/1, column_names/2,
@@ -39,7 +39,7 @@
-define(DEFAULT_TIMEOUT, 5000). -define(DEFAULT_TIMEOUT, 5000).
%% %%
-type connection() :: tuple(). -type connection() :: tuple().
-type statement() :: term(). -type statement() :: term().
-type sql() :: iolist(). -type sql() :: iolist().
@@ -47,14 +47,14 @@
%% @doc Opens a sqlite3 database mentioned in Filename. %% @doc Opens a sqlite3 database mentioned in Filename.
%% %%
-spec open(FileName) -> {ok, connection()} | {error, _} when -spec open(FileName) -> {ok, connection()} | {error, _} when
FileName :: string(). FileName :: string().
open(Filename) -> open(Filename) ->
open(Filename, ?DEFAULT_TIMEOUT). open(Filename, ?DEFAULT_TIMEOUT).
%% @doc Open a database connection %% @doc Open a database connection
%% %%
-spec open(Filename, timeout()) -> {ok, connection()} | {error, _} when -spec open(Filename, timeout()) -> {ok, connection()} | {error, _} when
Filename :: string(). Filename :: string().
open(Filename, Timeout) -> open(Filename, Timeout) ->
{ok, Connection} = esqlite3_nif:start(), {ok, Connection} = esqlite3_nif:start(),
@@ -76,9 +76,9 @@ q(Sql, Connection) ->
-spec q(sql(), list(), connection()) -> list(tuple()). -spec q(sql(), list(), connection()) -> list(tuple()).
q(Sql, [], Connection) -> q(Sql, [], Connection) ->
case prepare(Sql, Connection) of case prepare(Sql, Connection) of
{ok, Statement} -> {ok, Statement} ->
fetchall(Statement); fetchall(Statement);
{error, _Msg}=Error -> {error, _Msg}=Error ->
throw(Error) throw(Error)
end; end;
q(Sql, Args, Connection) -> q(Sql, Args, Connection) ->
@@ -86,29 +86,29 @@ q(Sql, Args, Connection) ->
{ok, Statement} -> {ok, Statement} ->
ok = bind(Statement, Args), ok = bind(Statement, Args),
fetchall(Statement); fetchall(Statement);
{error, _Msg}=Error -> {error, _Msg}=Error ->
throw(Error) throw(Error)
end. end.
%% @doc %% @doc
-spec map(F, sql(), connection()) -> list(Type) when -spec map(F, sql(), connection()) -> list(Type) when
F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type), F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
Row :: tuple(), Row :: tuple(),
ColumnNames :: tuple(), ColumnNames :: tuple(),
Type :: any(). Type :: any().
map(F, Sql, Connection) -> map(F, Sql, Connection) ->
case prepare(Sql, Connection) of case prepare(Sql, Connection) of
{ok, Statement} -> {ok, Statement} ->
map_s(F, Statement); map_s(F, Statement);
{error, _Msg}=Error -> {error, _Msg}=Error ->
throw(Error) throw(Error)
end. end.
%% @doc %% @doc
-spec foreach(F, sql(), connection()) -> ok when -spec foreach(F, sql(), connection()) -> ok when
F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()), F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()),
Row :: tuple(), Row :: tuple(),
ColumnNames :: tuple(). ColumnNames :: tuple().
foreach(F, Sql, Connection) -> foreach(F, Sql, Connection) ->
case prepare(Sql, Connection) of case prepare(Sql, Connection) of
{ok, Statement} -> {ok, Statement} ->
@@ -119,10 +119,10 @@ foreach(F, Sql, Connection) ->
%% %%
-spec foreach_s(F, statement()) -> ok when -spec foreach_s(F, statement()) -> ok when
F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()), F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()),
Row :: tuple(), Row :: tuple(),
ColumnNames :: tuple(). ColumnNames :: tuple().
foreach_s(F, Statement) when is_function(F, 1) -> foreach_s(F, Statement) when is_function(F, 1) ->
case try_step(Statement, 0) of case try_step(Statement, 0) of
'$done' -> ok; '$done' -> ok;
{error, _} = E -> F(E); {error, _} = E -> F(E);
@@ -135,22 +135,22 @@ foreach_s(F, Statement) when is_function(F, 2) ->
case try_step(Statement, 0) of case try_step(Statement, 0) of
'$done' -> ok; '$done' -> ok;
{error, _} = E -> F([], E); {error, _} = E -> F([], E);
{row, Row} -> {row, Row} ->
F(ColumnNames, Row), F(ColumnNames, Row),
foreach_s(F, Statement) foreach_s(F, Statement)
end. end.
%% %%
-spec map_s(F, statement()) -> list(Type) when -spec map_s(F, statement()) -> list(Type) when
F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type), F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
Row :: tuple(), Row :: tuple(),
ColumnNames :: tuple(), ColumnNames :: tuple(),
Type :: term(). Type :: term().
map_s(F, Statement) when is_function(F, 1) -> map_s(F, Statement) when is_function(F, 1) ->
case try_step(Statement, 0) of case try_step(Statement, 0) of
'$done' -> []; '$done' -> [];
{error, _} = E -> F(E); {error, _} = E -> F(E);
{row, Row} -> {row, Row} ->
[F(Row) | map_s(F, Statement)] [F(Row) | map_s(F, Statement)]
end; end;
map_s(F, Statement) when is_function(F, 2) -> map_s(F, Statement) when is_function(F, 2) ->
@@ -158,7 +158,7 @@ map_s(F, Statement) when is_function(F, 2) ->
case try_step(Statement, 0) of case try_step(Statement, 0) of
'$done' -> []; '$done' -> [];
{error, _} = E -> F([], E); {error, _} = E -> F([], E);
{row, Row} -> {row, Row} ->
[F(ColumnNames, Row) | map_s(F, Statement)] [F(ColumnNames, Row) | map_s(F, Statement)]
end. end.
@@ -171,37 +171,44 @@ fetchone(Statement) ->
{row, Row} -> Row {row, Row} -> Row
end. end.
%% %%
-spec fetchall(statement()) -> list(tuple()). -spec fetchall(statement()) ->
list(tuple()) |
{error, term()}.
fetchall(Statement) -> fetchall(Statement) ->
case try_step(Statement, 0) of case try_step(Statement, 0) of
'$done' -> '$done' ->
[]; [];
{error, _} = E -> E; {error, _} = E -> E;
{row, Row} -> {row, Row} ->
[Row | fetchall(Statement)] case fetchall(Statement) of
end. {error, _} = E -> E;
Rest -> [Row | Rest]
end
end.
%% Try the step, when the database is busy, %% Try the step, when the database is busy,
-spec try_step(statement(), non_neg_integer()) -> term(). -spec try_step(statement(), non_neg_integer()) ->
'$done' |
term().
try_step(_Statement, Tries) when Tries > 5 -> try_step(_Statement, Tries) when Tries > 5 ->
throw(too_many_tries); throw(too_many_tries);
try_step(Statement, Tries) -> try_step(Statement, Tries) ->
case esqlite3:step(Statement) of case esqlite3:step(Statement) of
'$busy' -> '$busy' ->
timer:sleep(100 * Tries), timer:sleep(100 * Tries),
try_step(Statement, Tries + 1); try_step(Statement, Tries + 1);
Something -> Something ->
Something Something
end. end.
%% @doc Execute Sql statement, returns the number of affected rows. %% @doc Execute Sql statement, returns the number of affected rows.
%% %%
%% @spec exec(iolist(), connection()) -> integer() | {error, error_message()} %% @spec exec(iolist(), connection()) -> integer() | {error, error_message()}
exec(Sql, Connection) -> exec(Sql, Connection) ->
exec(Sql, Connection, ?DEFAULT_TIMEOUT). exec(Sql, Connection, ?DEFAULT_TIMEOUT).
%% @doc Execute %% @doc Execute
%% %%
%% @spec exec(iolist(), connection(), timeout()) -> integer() | {error, error_message()} %% @spec exec(iolist(), connection(), timeout()) -> integer() | {error, error_message()}
exec(Sql, {connection, _Ref, Connection}, Timeout) -> exec(Sql, {connection, _Ref, Connection}, Timeout) ->
@@ -218,7 +225,7 @@ exec(Sql, Params, {connection, _, _}=Connection, Timeout) when is_list(Params) -
{ok, Statement} = prepare(Sql, Connection, Timeout), {ok, Statement} = prepare(Sql, Connection, Timeout),
bind(Statement, Params), bind(Statement, Params),
step(Statement, Timeout). step(Statement, Timeout).
%% @doc Return the number of affected rows of last statement. %% @doc Return the number of affected rows of last statement.
changes(Connection) -> changes(Connection) ->
@@ -264,9 +271,10 @@ prepare(Sql, {connection, _Ref, Connection}, Timeout) ->
step(Stmt) -> step(Stmt) ->
step(Stmt, ?DEFAULT_TIMEOUT). step(Stmt, ?DEFAULT_TIMEOUT).
%% @doc %% @doc
%% %%
%% @spec step(prepared_statement(), timeout()) -> tuple() %% @spec step(prepared_statement(), timeout()) -> tuple()
-spec step(term(), timeout()) -> tuple() | '$busy' | '$done'.
step(Stmt, Timeout) -> step(Stmt, Timeout) ->
Ref = make_ref(), Ref = make_ref(),
ok = esqlite3_nif:step(Stmt, Ref, self()), ok = esqlite3_nif:step(Stmt, Ref, self()),
@@ -338,17 +346,17 @@ close({connection, _Ref, Connection}, Timeout) ->
receive_answer(Ref, Timeout) -> receive_answer(Ref, Timeout) ->
Start = os:timestamp(), Start = os:timestamp(),
receive receive
{esqlite3, Ref, Resp} -> {esqlite3, Ref, Resp} ->
Resp; Resp;
{esqlite3, _, _}=StaleAnswer -> {esqlite3, _, _}=StaleAnswer ->
error_logger:warning_msg("Esqlite3: Ignoring stale answer ~p~n", [StaleAnswer]), error_logger:warning_msg("Esqlite3: Ignoring stale answer ~p~n", [StaleAnswer]),
PassedMics = timer:now_diff(os:timestamp(), Start) div 1000, PassedMics = timer:now_diff(os:timestamp(), Start) div 1000,
NewTimeout = case Timeout - PassedMics of NewTimeout = case Timeout - PassedMics of
Passed when Passed < 0 -> 0; Passed when Passed < 0 -> 0;
TO -> TO TO -> TO
end, end,
receive_answer(Ref, NewTimeout) receive_answer(Ref, NewTimeout)
after Timeout -> after Timeout ->
throw({error, timeout, Ref}) throw({error, timeout, Ref})
end. end.

View File

@@ -8,9 +8,9 @@
%% Licensed under the Apache License, Version 2.0 (the "License"); %% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License. %% you may not use this file except in compliance with the License.
%% You may obtain a copy of the License at %% You may obtain a copy of the License at
%% %%
%% http://www.apache.org/licenses/LICENSE-2.0 %% http://www.apache.org/licenses/LICENSE-2.0
%% %%
%% Unless required by applicable law or agreed to in writing, software %% Unless required by applicable law or agreed to in writing, software
%% distributed under the License is distributed on an "AS IS" BASIS, %% distributed under the License is distributed on an "AS IS" BASIS,
%% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. %% WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
@@ -22,19 +22,19 @@
%% low-level exports %% low-level exports
-export([start/0, -export([start/0,
open/4, open/4,
exec/4, exec/4,
changes/3, changes/3,
insert/4, insert/4,
prepare/4, prepare/4,
step/3, step/3,
reset/3, reset/3,
finalize/3, finalize/3,
bind/4, bind/4,
column_names/3, column_names/3,
column_types/3, column_types/3,
close/3 close/3
]). ]).
-on_load(init/0). -on_load(init/0).
@@ -46,23 +46,24 @@ init() ->
end, end,
ok = erlang:load_nif(NifFileName, 0). ok = erlang:load_nif(NifFileName, 0).
%% @doc Start a low level thread which will can handle sqlite3 calls. %% @doc Start a low level thread which will can handle sqlite3 calls.
%% %%
%% @spec start() -> {ok, connection()} | {error, msg()} %% @spec start() -> {ok, connection()} | {error, msg()}
start() -> start() ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Open the specified sqlite3 database. %% @doc Open the specified sqlite3 database.
%% %%
%% Sends an asynchronous open command over the connection and returns %% Sends an asynchronous open command over the connection and returns
%% ok immediately. When the database is opened %% ok immediately. When the database is opened
%% %%
%% @spec open(connection(), reference(), pid(), string()) -> ok | {error, message()} %% @spec open(connection(), reference(), pid(), string()) -> ok | {error, message()}
open(_Db, _Ref, _Dest, _Filename) -> open(_Db, _Ref, _Dest, _Filename) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Exec the query. %% @doc Exec the query.
%% %%
%% Sends an asynchronous exec command over the connection and returns %% Sends an asynchronous exec command over the connection and returns
%% ok immediately. %% ok immediately.
%% %%
@@ -71,70 +72,67 @@ open(_Db, _Ref, _Dest, _Filename) ->
%% %%
%% @spec exec(connection(), Ref::reference(), Dest::pid(), string()) -> ok | {error, message()} %% @spec exec(connection(), Ref::reference(), Dest::pid(), string()) -> ok | {error, message()}
exec(_Db, _Ref, _Dest, _Sql) -> exec(_Db, _Ref, _Dest, _Sql) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Get the number of affected rows of last statement %% @doc Get the number of affected rows of last statement
%% %%
%% When the statement is executed Dest will receive message {Ref, answer()} %% When the statement is executed Dest will receive message {Ref, answer()}
%% with answer() integer | {error, reason()} %% with answer() integer | {error, reason()}
%% %%
changes(_Db, _Ref, _Dest) -> changes(_Db, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc %% @doc
%% %%
%% @spec prepare(connection(), reference(), pid(), string()) -> ok | {error, message()} %% @spec prepare(connection(), reference(), pid(), string()) -> ok | {error, message()}
prepare(_Db, _Ref, _Dest, _Sql) -> prepare(_Db, _Ref, _Dest, _Sql) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc %% @doc
%% %%
%% @spec step(statement(), reference(), pid()) -> ok | {error, message()} %% @spec step(statement(), reference(), pid()) -> ok | {error, message()}
step(_Stmt, _Ref, _Dest) -> step(_Stmt, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc %% @doc
%% %%
%% @spec reset(statement(), reference(), pid()) -> ok | {error, message()} %% @spec reset(statement(), reference(), pid()) -> ok | {error, message()}
reset(_Stmt, _Ref, _Dest) -> reset(_Stmt, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc %% @doc
%% %%
%% %%
finalize(_Stmt, _Ref, _Dest) -> finalize(_Stmt, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Bind parameters to a prepared statement. %% @doc Bind parameters to a prepared statement.
%% %%
%% @spec bind(statement(), reference(), pid(), []) -> ok | {error, message()} %% @spec bind(statement(), reference(), pid(), []) -> ok | {error, message()}
bind(_Stmt, _Ref, _Dest, _Args) -> bind(_Stmt, _Ref, _Dest, _Args) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Retrieve the column names of the prepared statement %% @doc Retrieve the column names of the prepared statement
%% %%
%% @spec column_names(statement(), reference(), pid()) -> {ok, tuple()} | {error, message()} %% @spec column_names(statement(), reference(), pid()) -> {ok, tuple()} | {error, message()}
column_names(_Stmt, _Ref, _Dest) -> column_names(_Stmt, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Retrieve the column types of the prepared statement %% @doc Retrieve the column types of the prepared statement
%% %%
%% @spec column_types(statement(), reference(), pid()) -> {ok, tuple()} | {error, message()} %% @spec column_types(statement(), reference(), pid()) -> {ok, tuple()} | {error, message()}
column_types(_Stmt, _Ref, _Dest) -> column_types(_Stmt, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Close the connection. %% @doc Close the connection.
%% %%
%% @spec close(connection(), reference(), pid()) -> ok | {error, message()} %% @spec close(connection(), reference(), pid()) -> ok | {error, message()}
close(_Db, _Ref, _Dest) -> close(_Db, _Ref, _Dest) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Insert record %% @doc Insert record
%% %%
%% @spec insert(connection(), Ref::reference(), Dest::pid(), string()) -> {ok, integer()} | {error, message()} %% @spec insert(connection(), Ref::reference(), Dest::pid(), string()) -> {ok, integer()} | {error, message()}
insert(_Db, _Ref, _Dest, _Sql) -> insert(_Db, _Ref, _Dest, _Sql) ->
exit(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).