Added specs

This commit is contained in:
Maas-Maarten Zeeman
2012-12-26 23:51:54 +01:00
parent 3697633c6b
commit 827a8c1756
3 changed files with 56 additions and 31 deletions

View File

@@ -1,5 +1,5 @@
/*
* Copyright 2011 Maas-Maarten Zeeman
* Copyright 2011, 2012 Maas-Maarten Zeeman
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
@@ -21,8 +21,6 @@
#include <erl_nif.h>
#include <string.h>
#include <stdio.h> /* for debugging */
#include "queue.h"
#include "sqlite3.h"

View File

@@ -1,9 +1,9 @@
%% @author Maas-Maarten Zeeman <mmzeeman@xs4all.nl>
%% @copyright 2011 Maas-Maarten Zeeman
%% @copyright 2011, 2012 Maas-Maarten Zeeman
%% @doc Erlang API for sqlite3 databases
%% Copyright 2011 Maas-Maarten Zeeman
%% Copyright 2011, 2012 Maas-Maarten Zeeman
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.
@@ -33,17 +33,24 @@
-export([q/2, q/3, map/3, foreach/3]).
-define(DEFAULT_TIMEOUT, infinity).
-define(DEFAULT_TIMEOUT, 5000).
%%
-type connection() :: tuple().
-type statement() :: term().
-type sql() :: iolist().
%% @doc Opens a sqlite3 database mentioned in Filename.
%%
%% @spec open(string()) -> {ok, connection()} | {error, error_message()}
-spec open(FileName) -> {ok, connection()} | {error, _} when
FileName :: string().
open(Filename) ->
open(Filename, ?DEFAULT_TIMEOUT).
%% @doc Open a database connection
%%
%% @spec open(string(), timeout()) -> {ok, connection()} | {error, error_message()}
-spec open(Filename, timeout()) -> {ok, connection()} | {error, _} when
Filename :: string().
open(Filename, Timeout) ->
{ok, Connection} = esqlite3_nif:start(),
@@ -51,51 +58,66 @@ open(Filename, Timeout) ->
ok = esqlite3_nif:open(Connection, Ref, self(), Filename),
case receive_answer(Ref, Timeout) of
ok ->
{ok, Connection};
{ok, {connection, make_ref(), Connection}};
{error, _Msg}=Error ->
Error
end.
%% @doc Execute a sql statement, returns a list with tuples.
%% @doc Execute a sql statement, returns a list with tuples.
-spec q(sql(), connection()) -> list(tuple()).
q(Sql, Connection) ->
q(Sql, [], Connection).
%% @doc Execute statement, bind args and return a list with tuples as result.
-spec q(sql(), list(), connection()) -> list(tuple()).
q(Sql, [], Connection) ->
case prepare(Sql, Connection) of
{ok, Statement} ->
fetchall(Statement);
{error, _Msg}=E ->
throw(E)
{error, _Msg}=Error ->
throw(Error)
end;
q(Sql, Args, Connection) ->
case prepare(Sql, Connection) of
{ok, Statement} ->
ok = bind(Statement, Args),
fetchall(Statement);
{error, _Msg}=E ->
throw(E)
{error, _Msg}=Error ->
throw(Error)
end.
%%
%% @doc
-spec map(F, sql(), connection()) -> list(Type) when
F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
Row :: tuple(),
ColumnNames :: tuple(),
Type :: any().
map(F, Sql, Connection) ->
case prepare(Sql, Connection) of
{ok, Statement} ->
map_s(F, Statement);
{error, _Msg}=E ->
throw(E)
{error, _Msg}=Error ->
throw(Error)
end.
%%
%% @doc
-spec foreach(F, sql(), connection()) -> ok when
F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()),
Row :: tuple(),
ColumnNames :: tuple().
foreach(F, Sql, Connection) ->
case prepare(Sql, Connection) of
{ok, Statement} ->
foreach_s(F, Statement);
{error, _Msg}=E ->
throw(E)
{error, _Msg}=Error ->
throw(Error)
end.
%%
-spec foreach_s(F, statement()) -> ok when
F :: fun((Row) -> any()) | fun((ColumnNames, Row) -> any()),
Row :: tuple(),
ColumnNames :: tuple().
foreach_s(F, Statement) when is_function(F, 1) ->
case try_step(Statement, 0) of
'$done' -> ok;
@@ -113,6 +135,11 @@ foreach_s(F, Statement) when is_function(F, 2) ->
end.
%%
-spec map_s(F, statement()) -> list(Type) when
F :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
Row :: tuple(),
ColumnNames :: tuple(),
Type :: term().
map_s(F, Statement) when is_function(F, 1) ->
case try_step(Statement, 0) of
'$done' -> [];
@@ -128,13 +155,15 @@ map_s(F, Statement) when is_function(F, 2) ->
end.
%%
-spec fetchone(statement()) -> tuple().
fetchone(Statement) ->
case try_step(Statement, 0) of
'$done' -> ok;
{row, Row} -> Row
end.
%%
%%
-spec fetchall(statement()) -> list(tuple()).
fetchall(Statement) ->
case try_step(Statement, 0) of
'$done' ->
@@ -144,6 +173,7 @@ fetchall(Statement) ->
end.
%% Try the step, when the database is busy,
-spec try_step(statement(), non_neg_integer()) -> term().
try_step(_Statement, Tries) when Tries > 5 ->
throw(too_many_tries);
try_step(Statement, Tries) ->
@@ -164,7 +194,7 @@ exec(Sql, Connection) ->
%% @doc Execute
%%
%% @spec exec(iolist(), connection(), timeout()) -> integer() | {error, error_message()}
exec(Sql, Connection, Timeout) ->
exec(Sql, {connection, _Ref, Connection}, Timeout) ->
Ref = make_ref(),
ok = esqlite3_nif:exec(Connection, Ref, self(), add_eos(Sql)),
receive_answer(Ref, Timeout).
@@ -178,7 +208,7 @@ prepare(Sql, Connection) ->
%% @doc
%%
%% @spec(iolist(), connection(), timeout()) -> {ok, prepared_statement()} | {error, error_message()}
prepare(Sql, Connection, Timeout) ->
prepare(Sql, {connection, _Ref, Connection}, Timeout) ->
Ref = make_ref(),
ok = esqlite3_nif:prepare(Connection, Ref, self(), add_eos(Sql)),
receive_answer(Ref, Timeout).
@@ -224,13 +254,15 @@ column_names(Stmt, Timeout) ->
%% @doc Close the database
%%
%% @spec close(connection()) -> ok | {error, error_message()}
-spec close(connection()) -> ok | {error, _}.
close(Connection) ->
close(Connection, ?DEFAULT_TIMEOUT).
%% @doc Close the database
%%
%% @spec close(connection(), integer()) -> ok | {error, error_message()}
close(Connection, Timeout) ->
-spec close(connection(), timeout()) -> ok | {error, _}.
close({connection, _Ref, Connection}, Timeout) ->
Ref = make_ref(),
ok = esqlite3_nif:close(Connection, Ref, self()),
receive_answer(Ref, Timeout).
@@ -246,8 +278,3 @@ receive_answer(Ref, Timeout) ->
after Timeout ->
throw({error, timeout, Ref})
end.

View File

@@ -1,9 +1,9 @@
%% @author Maas-Maarten Zeeman <mmzeeman@xs4all.nl>
%% @copyright 2011 Maas-Maarten Zeeman
%% @copyright 2011, 2012 Maas-Maarten Zeeman
%% @doc Low level erlang API for sqlite3 databases
%% Copyright 2011 Maas-Maarten Zeeman
%% Copyright 2011, 2012 Maas-Maarten Zeeman
%%
%% Licensed under the Apache License, Version 2.0 (the "License");
%% you may not use this file except in compliance with the License.