Implement get_autocommit

http://www.sqlite.org/c3ref/get_autocommit.html
This commit is contained in:
connor rigby
2018-12-02 11:10:03 -08:00
parent 2dd24c5381
commit d014a4d525
4 changed files with 74 additions and 2 deletions

View File

@@ -63,7 +63,8 @@ typedef enum {
cmd_column_types,
cmd_close,
cmd_stop,
cmd_insert
cmd_insert,
cmd_get_autocommit,
} command_type;
typedef struct {
@@ -486,6 +487,16 @@ do_bind(ErlNifEnv *env, sqlite3 *db, sqlite3_stmt *stmt, const ERL_NIF_TERM arg)
return make_atom(env, "ok");
}
static ERL_NIF_TERM
do_get_autocommit(ErlNifEnv *env, esqlite_connection *conn)
{
if(sqlite3_get_autocommit(conn->db) != 0) {
return make_atom(env, "true");
} else {
return make_atom(env, "false");
}
}
static ERL_NIF_TERM
make_binary(ErlNifEnv *env, const void *bytes, unsigned int size)
{
@@ -716,6 +727,8 @@ evaluate_command(esqlite_command *cmd, esqlite_connection *conn)
return do_close(cmd->env, conn, cmd->arg);
case cmd_insert:
return do_insert(cmd->env, conn, cmd->arg);
case cmd_get_autocommit:
return do_get_autocommit(cmd->env, conn);
default:
return make_error_tuple(cmd->env, "invalid_command");
}
@@ -951,6 +964,34 @@ esqlite_insert(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
return push_command(env, db, cmd);
}
static ERL_NIF_TERM
esqlite_get_autocommit(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
{
esqlite_connection *db;
esqlite_command *cmd = NULL;
ErlNifPid pid;
if(argc != 3)
return enif_make_badarg(env);
if(!enif_get_resource(env, argv[0], esqlite_connection_type, (void **) &db))
return enif_make_badarg(env);
if(!enif_is_ref(env, argv[1]))
return make_error_tuple(env, "invalid_ref");
if(!enif_get_local_pid(env, argv[2], &pid))
return make_error_tuple(env, "invalid_pid");
cmd = command_create();
if(!cmd)
return make_error_tuple(env, "command_create_failed");
/* command */
cmd->type = cmd_get_autocommit;
cmd->ref = enif_make_copy(cmd->env, argv[1]);
cmd->pid = pid;
return push_command(env, db, cmd);
}
/*
* Prepare the sql statement
*/
@@ -1245,6 +1286,7 @@ static ErlNifFunc nif_funcs[] = {
{"changes", 3, esqlite_changes},
{"prepare", 4, esqlite_prepare},
{"insert", 4, esqlite_insert},
{"get_autocommit", 3, esqlite_get_autocommit},
{"multi_step", 5, esqlite_multi_step},
{"reset", 4, esqlite_reset},
// TODO: {"esqlite_bind", 3, esqlite_bind_named},

View File

@@ -26,6 +26,8 @@
exec/2, exec/3,
changes/1, changes/2,
insert/2,
get_autocommit/1,
get_autocommit/2,
prepare/2, prepare/3,
step/1, step/2,
reset/1,
@@ -293,6 +295,17 @@ insert(Sql, {connection, _Ref, Connection}, Timeout) ->
ok = esqlite3_nif:insert(Connection, Ref, self(), Sql),
receive_answer(Ref, Timeout).
%% @doc Get autocommit
%%
%% @spec get_autocommit(connection) -> true | false
get_autocommit(Connection) ->
get_autocommit(Connection, ?DEFAULT_TIMEOUT).
get_autocommit({connection, _Ref, Connection}, Timeout) ->
Ref = make_ref(),
ok = esqlite3_nif:get_autocommit(Connection, Ref, self()),
receive_answer(Ref, Timeout).
%% @doc Prepare a statement
%%
%% @spec prepare(iolist(), connection()) -> {ok, prepared_statement()} | {error, error_message()}

View File

@@ -27,6 +27,7 @@
exec/4,
changes/3,
insert/4,
get_autocommit/3,
prepare/4,
multi_step/5,
reset/4,
@@ -140,3 +141,9 @@ close(_Db, _Ref, _Dest) ->
%% @spec insert(connection(), Ref::reference(), Dest::pid(), string()) -> {ok, integer()} | {error, message()}
insert(_Db, _Ref, _Dest, _Sql) ->
erlang:nif_error(nif_library_not_loaded).
%% @doc Get automcommit
%%
%% @spec get_autocommit(connection(), Ref::reference(), Dest::pid()) -> true | false
get_autocommit(_Db, _Ref, _Dest) ->
erlang:nif_error(nif_library_not_loaded).

View File

@@ -20,6 +20,17 @@ open_multiple_different_databases_test() ->
{ok, _C2} = esqlite3:open("test2.db"),
ok.
get_autocommit_test() ->
{ok, Db} = esqlite3:open(":memory:"),
ok = esqlite3:exec("CREATE TABLE test (id INTEGER PRIMARY KEY, val STRING);", Db),
true = esqlite3:get_autocommit(Db),
ok = esqlite3:exec("BEGIN;", Db),
false = esqlite3:get_autocommit(Db),
ok = esqlite3:exec("INSERT INTO test (val) VALUES ('this is a test');", Db),
ok = esqlite3:exec("COMMIT;", Db),
true = esqlite3:get_autocommit(Db),
ok.
update_hook_test() ->
{ok, Db} = esqlite3:open(":memory:"),
ok = esqlite3:set_update_hook(self(), Db),
@@ -32,7 +43,6 @@ update_hook_test() ->
ok = receive {delete, "test", 1} -> ok after 150 -> no_message end,
ok.
simple_query_test() ->
{ok, Db} = esqlite3:open(":memory:"),
ok = esqlite3:exec("begin;", Db),