From a0155800215180315200a6e43432641ea2eac880 Mon Sep 17 00:00:00 2001 From: Maas-Maarten Zeeman Date: Sun, 6 Nov 2011 21:37:35 +0100 Subject: [PATCH] Split off low-level api in separate file --- c_src/{esqlite_nif.c => esqlite3_nif.c} | 22 +++---- rebar.config | 2 +- src/{esqlite.erl => esqlite3.erl} | 60 +++--------------- src/esqlite3_nif.erl | 57 +++++++++++++++++ src/sqlite.erl | 8 +-- test/esqlite_test.erl | 84 ++++++++++++------------- 6 files changed, 123 insertions(+), 110 deletions(-) rename c_src/{esqlite_nif.c => esqlite3_nif.c} (97%) rename src/{esqlite.erl => esqlite3.erl} (69%) create mode 100644 src/esqlite3_nif.erl diff --git a/c_src/esqlite_nif.c b/c_src/esqlite3_nif.c similarity index 97% rename from c_src/esqlite_nif.c rename to c_src/esqlite3_nif.c index d783909..5a5dfd9 100644 --- a/c_src/esqlite_nif.c +++ b/c_src/esqlite3_nif.c @@ -1,5 +1,5 @@ /* - * Esqlite -- an erlang sqlite nif. + * sqlite3_nif -- an erlang sqlite nif. */ #include @@ -708,13 +708,13 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) { ErlNifResourceType *rt; - rt = enif_open_resource_type(env, "esqlite", "esqlite_connection_type", + rt = enif_open_resource_type(env, "esqlite3_nif", "esqlite_connection_type", destruct_esqlite_connection, ERL_NIF_RT_CREATE, NULL); if(!rt) return -1; esqlite_connection_type = rt; - rt = enif_open_resource_type(env, "esqlite", "esqlite_statement_type", + rt = enif_open_resource_type(env, "esqlite3_nif", "esqlite_statement_type", destruct_esqlite_statement, ERL_NIF_RT_CREATE, NULL); if(!rt) return -1; @@ -727,14 +727,14 @@ on_load(ErlNifEnv* env, void** priv, ERL_NIF_TERM info) } static ErlNifFunc nif_funcs[] = { - {"esqlite_start", 0, esqlite_start}, - {"esqlite_open", 4, esqlite_open}, - {"esqlite_exec", 4, esqlite_exec}, - {"esqlite_prepare", 4, esqlite_prepare}, - {"esqlite_step", 3, esqlite_step}, + {"start", 0, esqlite_start}, + {"open", 4, esqlite_open}, + {"exec", 4, esqlite_exec}, + {"prepare", 4, esqlite_prepare}, + {"step", 3, esqlite_step}, // {"esqlite_bind", 3, esqlite_bind_named}, - {"esqlite_bind", 4, esqlite_bind}, - {"esqlite_close", 3, esqlite_close} + {"bind", 4, esqlite_bind}, + {"close", 3, esqlite_close} }; -ERL_NIF_INIT(esqlite, nif_funcs, on_load, NULL, NULL, NULL); +ERL_NIF_INIT(esqlite3_nif, nif_funcs, on_load, NULL, NULL, NULL); diff --git a/rebar.config b/rebar.config index 4bf4d0d..e3e3e3c 100644 --- a/rebar.config +++ b/rebar.config @@ -1,3 +1,3 @@ {require_otp_vsn, "R14"}. {port_sources, ["c_src/*.c"]}. -{so_name, "esqlite_nif.so"}. +{so_name, "esqlite3_nif.so"}. diff --git a/src/esqlite.erl b/src/esqlite3.erl similarity index 69% rename from src/esqlite.erl rename to src/esqlite3.erl index 92f4986..aa2325f 100644 --- a/src/esqlite.erl +++ b/src/esqlite3.erl @@ -2,7 +2,7 @@ %% %% --module(esqlite). +-module(esqlite3). -author("Maas-Maarten Zeeman "). %% higher-level export @@ -13,23 +13,8 @@ bind/2, bind/3, close/1, close/2]). -%% low-level exports --export([esqlite_start/0, - esqlite_open/4, - esqlite_exec/4, - esqlite_prepare/4, - esqlite_step/3, - esqlite_bind/4, - esqlite_close/3 -]). - --on_load(init/0). - -define(DEFAULT_TIMEOUT, infinity). -init() -> - ok = erlang:load_nif(code:priv_dir(esqlite) ++ "/esqlite_nif", 0). - %% @doc Opens a sqlite3 database mentioned in Filename. %% %% @spec open(string()) -> {ok, connection()} | {error, error_message()} @@ -40,10 +25,10 @@ open(Filename) -> %% %% @spec open(string(), integer()) -> {ok, connection()} | {error, error_message()} open(Filename, Timeout) -> - {ok, Db} = esqlite_start(), + {ok, Db} = esqlite3_nif:start(), Ref = make_ref(), - ok = esqlite_open(Db, Ref, self(), Filename), + ok = esqlite3_nif:open(Db, Ref, self(), Filename), case receive_answer(Ref, Timeout) of ok -> {ok, Db}; @@ -62,7 +47,7 @@ exec(Db, Sql) -> %% @spec exec(connection(), iolist(), integer()) -> integer() | {error, error_message()} exec(Db, Sql, Timeout) -> Ref = make_ref(), - ok = esqlite_exec(Db, Ref, self(), add_eos(Sql)), + ok = esqlite3_nif:exec(Db, Ref, self(), add_eos(Sql)), receive_answer(Ref, Timeout). %% @doc Prepare a statement @@ -76,7 +61,7 @@ prepare(Db, Sql) -> %% @spec(connection(), iolist()) -> {ok, prepared_statement()} | {error, error_message()} prepare(Db, Sql, Timeout) -> Ref = make_ref(), - ok = esqlite_prepare(Db, Ref, self(), add_eos(Sql)), + ok = esqlite3_nif:prepare(Db, Ref, self(), add_eos(Sql)), receive_answer(Ref, Timeout). %% @doc Step @@ -90,7 +75,7 @@ step(Stmt) -> %% @spec step(prepared_statement(), integer()) -> tuple() step(Stmt, Timeout) -> Ref = make_ref(), - ok = esqlite_step(Stmt, Ref, self()), + ok = esqlite3_nif:step(Stmt, Ref, self()), receive_answer(Ref, Timeout). %% @doc Bind values to prepared statements @@ -104,7 +89,7 @@ bind(Stmt, Args) -> %% @spec bind(prepared_statement()) -> ok | {error, error_message()} bind(Stmt, Args, Timeout) -> Ref = make_ref(), - ok = esqlite_bind(Stmt, Ref, self(), Args), + ok = esqlite3_nif:bind(Stmt, Ref, self(), Args), receive_answer(Ref, Timeout). %% @doc Close the database @@ -118,38 +103,9 @@ close(Db) -> %% @spec close(connection(), integer()) -> ok | {error, error_message()} close(Db, Timeout) -> Ref = make_ref(), - ok = esqlite_close(Db, Ref, self()), + ok = esqlite3_nif:close(Db, Ref, self()), receive_answer(Ref, Timeout). -%% @doc -%% -esqlite_start() -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_open(_Db, _Ref, _Dest, _Filename) -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_exec(_Db, _Ref, _Dest, _Sql) -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_prepare(_Db, _Ref, _Dest, _Sql) -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_step(_Stmt, _Ref, _Dest) -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_bind(_Stmt, _Ref, _Dest, _Args) -> - exit(nif_library_not_loaded). - -%% @doc -esqlite_close(_Db, _Ref, _Dest) -> - exit(nif_library_not_loaded). - %% Internal functions add_eos(String) when is_list(String) -> diff --git a/src/esqlite3_nif.erl b/src/esqlite3_nif.erl new file mode 100644 index 0000000..ec33a55 --- /dev/null +++ b/src/esqlite3_nif.erl @@ -0,0 +1,57 @@ +%% +%% +%% + +-module(esqlite3_nif). +-author("Maas-Maarten Zeeman "). + +%% low-level exports +-export([start/0, + open/4, + exec/4, + prepare/4, + step/3, + bind/4, + close/3 +]). + +-on_load(init/0). + +init() -> + ok = erlang:load_nif(code:priv_dir(esqlite) ++ "/esqlite3_nif", 0). + +%% @doc Start a low level thread which will can handle sqlite3 calls. +%% +%% @spec +start() -> + exit(nif_library_not_loaded). + +%% @doc Open a connection to +%% +open(_Db, _Ref, _Dest, _Filename) -> + exit(nif_library_not_loaded). + +%% @doc +exec(_Db, _Ref, _Dest, _Sql) -> + exit(nif_library_not_loaded). + +%% @doc +prepare(_Db, _Ref, _Dest, _Sql) -> + exit(nif_library_not_loaded). + +%% @doc +step(_Stmt, _Ref, _Dest) -> + exit(nif_library_not_loaded). + +%% @doc +bind(_Stmt, _Ref, _Dest, _Args) -> + exit(nif_library_not_loaded). + +%% @doc +close(_Db, _Ref, _Dest) -> + exit(nif_library_not_loaded). + + + + + diff --git a/src/sqlite.erl b/src/sqlite.erl index 0e82dfd..6c07188 100644 --- a/src/sqlite.erl +++ b/src/sqlite.erl @@ -11,13 +11,13 @@ %% @doc Open a database connection %% handle_open(DatabaseName) -> - esqlite:open(DatabaseName). + esqlite3:open(DatabaseName). %% @doc Execute a query and return the results %% handle_execute(Operation, Args, Connection) -> - {ok, Stmt} = esqlite:prepare(Connection, Operation), - ok = esqlite:bind(Stmt, Args), + {ok, Stmt} = esqlite3:prepare(Connection, Operation), + ok = esqlite3:bind(Stmt, Args), Answer = execute(Stmt), %% TODO Finalize the statement. Answer. @@ -38,7 +38,7 @@ execute(Statement) -> execute(_Statement, _Acc, Tries) when Tries > 5 -> throw(too_many_tries); execute(Statement, Acc, Tries) -> - case esqlite:step(Statement) of + case esqlite3:step(Statement) of '$done' -> lists:reverse(Acc); '$busy' -> diff --git a/test/esqlite_test.erl b/test/esqlite_test.erl index 5cf8578..07602f1 100644 --- a/test/esqlite_test.erl +++ b/test/esqlite_test.erl @@ -7,65 +7,65 @@ -include_lib("eunit/include/eunit.hrl"). open_single_database_test() -> - {ok, _C1} = esqlite:open("test.db"), + {ok, _C1} = esqlite3:open("test.db"), ok. open_multiple_same_databases_test() -> - {ok, _C1} = esqlite:open("test.db"), - {ok, _C2} = esqlite:open("test.db"), + {ok, _C1} = esqlite3:open("test.db"), + {ok, _C2} = esqlite3:open("test.db"), ok. open_multiple_different_databases_test() -> - {ok, _C1} = esqlite:open("test1.db"), - {ok, _C2} = esqlite:open("test2.db"), + {ok, _C1} = esqlite3:open("test1.db"), + {ok, _C2} = esqlite3:open("test2.db"), ok. simple_query_test() -> - {ok, Db} = esqlite:open(":memory:"), - ok = esqlite:exec(Db, "begin;"), - ok = esqlite:exec(Db, "create table test_table(one varchar(10), two int);"), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello1\"", ",", "10" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello2\"", ",", "11" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello3\"", ",", "12" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), - ok = esqlite:exec(Db, "commit;"), - ok = esqlite:exec(Db, "select * from test_table;"), + {ok, Db} = esqlite3:open(":memory:"), + ok = esqlite3:exec(Db, "begin;"), + ok = esqlite3:exec(Db, "create table test_table(one varchar(10), two int);"), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello1\"", ",", "10" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello2\"", ",", "11" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello3\"", ",", "12" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), + ok = esqlite3:exec(Db, "commit;"), + ok = esqlite3:exec(Db, "select * from test_table;"), ok. prepare_test() -> - {ok, Db} = esqlite:open(":memory:"), - esqlite:exec(Db, "begin;"), - esqlite:exec(Db, "create table test_table(one varchar(10), two int);"), - {ok, Statement} = esqlite:prepare(Db, "insert into test_table values(\"one\", 2)"), + {ok, Db} = esqlite3:open(":memory:"), + esqlite3:exec(Db, "begin;"), + esqlite3:exec(Db, "create table test_table(one varchar(10), two int);"), + {ok, Statement} = esqlite3:prepare(Db, "insert into test_table values(\"one\", 2)"), - '$done' = esqlite:step(Statement), + '$done' = esqlite3:step(Statement), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), - {ok, St2} = esqlite:prepare(Db, "select * from test_table order by two"), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), + {ok, St2} = esqlite3:prepare(Db, "select * from test_table order by two"), [{"one", 2}, {"hello4", 13}] = exec(St2), - esqlite:exec(Db, "commit;"), - esqlite:close(Db), + esqlite3:exec(Db, "commit;"), + esqlite3:close(Db), ok. bind_test() -> - {ok, Db} = esqlite:open(":memory:"), - ok = esqlite:exec(Db, "begin;"), - ok = esqlite:exec(Db, "create table test_table(one varchar(10), two int);"), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello1\"", ",", "10" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello2\"", ",", "11" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello3\"", ",", "12" ");"]), - ok = esqlite:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), - ok = esqlite:exec(Db, "commit;"), + {ok, Db} = esqlite3:open(":memory:"), + ok = esqlite3:exec(Db, "begin;"), + ok = esqlite3:exec(Db, "create table test_table(one varchar(10), two int);"), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello1\"", ",", "10" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello2\"", ",", "11" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello3\"", ",", "12" ");"]), + ok = esqlite3:exec(Db, ["insert into test_table values(", "\"hello4\"", ",", "13" ");"]), + ok = esqlite3:exec(Db, "commit;"), %% Create a prepared statement - {ok, Statement} = esqlite:prepare(Db, "insert into test_table values(?1, ?2)"), - esqlite:bind(Statement, [one, 2]), - esqlite:step(Statement), - esqlite:bind(Statement, ["three", 4]), - esqlite:step(Statement), - esqlite:bind(Statement, [<<"five">>, 6]), - esqlite:step(Statement), + {ok, Statement} = esqlite3:prepare(Db, "insert into test_table values(?1, ?2)"), + esqlite3:bind(Statement, [one, 2]), + esqlite3:step(Statement), + esqlite3:bind(Statement, ["three", 4]), + esqlite3:step(Statement), + esqlite3:bind(Statement, [<<"five">>, 6]), + esqlite3:step(Statement), [{"one", 2}] = q(Db, "select * from test_table where two = '2'"), [{"three", 4}] = q(Db, "select * from test_table where two = 4"), @@ -84,14 +84,14 @@ gen_db_test() -> %% Handy functions... %% q(Connection, Sql) -> - {ok, Statement} = esqlite:prepare(Connection, Sql), + {ok, Statement} = esqlite3:prepare(Connection, Sql), exec(Statement). q(Connection, Sql, []) -> q(Connection, Sql); q(Connection, Sql, Args) -> - {ok, Statement} = esqlite:prepare(Connection, Sql), - esqlite:bind(Statement, Args), + {ok, Statement} = esqlite3:prepare(Connection, Sql), + esqlite3:bind(Statement, Args), exec(Statement). @@ -101,7 +101,7 @@ exec(Statement) -> exec(_Statement, _Acc, Tries) when Tries > 5 -> throw(too_many_tries); exec(Statement, Acc, Tries) -> - case esqlite:step(Statement) of + case esqlite3:step(Statement) of '$done' -> lists:reverse(Acc); '$busy' ->