Merge pull request #5 from qingliangcn/master
add insert function to get last insert rowid
This commit is contained in:
@@ -57,7 +57,8 @@ typedef enum {
|
|||||||
cmd_step,
|
cmd_step,
|
||||||
cmd_column_names,
|
cmd_column_names,
|
||||||
cmd_close,
|
cmd_close,
|
||||||
cmd_stop
|
cmd_stop,
|
||||||
|
cmd_insert
|
||||||
} command_type;
|
} command_type;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@@ -277,6 +278,27 @@ do_exec(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg)
|
|||||||
return make_atom(env, "ok");
|
return make_atom(env, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* insert action
|
||||||
|
*/
|
||||||
|
static ERL_NIF_TERM
|
||||||
|
do_insert(ErlNifEnv *env, esqlite_connection *conn, const ERL_NIF_TERM arg)
|
||||||
|
{
|
||||||
|
ErlNifBinary bin;
|
||||||
|
int rc;
|
||||||
|
ERL_NIF_TERM eos = enif_make_int(env, 0);
|
||||||
|
|
||||||
|
enif_inspect_iolist_as_binary(env,
|
||||||
|
enif_make_list2(env, arg, eos), &bin);
|
||||||
|
|
||||||
|
rc = sqlite3_exec(conn->db, (char *) bin.data, NULL, NULL, NULL);
|
||||||
|
if(rc != SQLITE_OK)
|
||||||
|
return make_sqlite3_error_tuple(env, rc, conn->db);
|
||||||
|
sqlite3_int64 last_rowid = sqlite3_last_insert_rowid(conn->db);
|
||||||
|
ERL_NIF_TERM last_rowid_term = enif_make_int(env, last_rowid);
|
||||||
|
return make_ok_tuple(env, last_rowid_term);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
*/
|
*/
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
@@ -530,6 +552,8 @@ evaluate_command(esqlite_command *cmd, esqlite_connection *conn)
|
|||||||
return do_column_names(cmd->env, cmd->stmt);
|
return do_column_names(cmd->env, cmd->stmt);
|
||||||
case cmd_close:
|
case cmd_close:
|
||||||
return do_close(cmd->env, conn, cmd->arg);
|
return do_close(cmd->env, conn, cmd->arg);
|
||||||
|
case cmd_insert:
|
||||||
|
return do_insert(cmd->env, conn, cmd->arg);
|
||||||
default:
|
default:
|
||||||
return make_error_tuple(cmd->env, "invalid_command");
|
return make_error_tuple(cmd->env, "invalid_command");
|
||||||
}
|
}
|
||||||
@@ -673,6 +697,35 @@ esqlite_exec(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
return push_command(env, db, cmd);
|
return push_command(env, db, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static ERL_NIF_TERM
|
||||||
|
esqlite_insert(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
|
{
|
||||||
|
esqlite_connection *db;
|
||||||
|
esqlite_command *cmd = NULL;
|
||||||
|
ErlNifPid pid;
|
||||||
|
|
||||||
|
if(argc != 4)
|
||||||
|
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_insert;
|
||||||
|
cmd->ref = enif_make_copy(cmd->env, argv[1]);
|
||||||
|
cmd->pid = pid;
|
||||||
|
cmd->arg = enif_make_copy(cmd->env, argv[3]);
|
||||||
|
|
||||||
|
return push_command(env, db, cmd);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Prepare the sql statement
|
* Prepare the sql statement
|
||||||
@@ -884,6 +937,7 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"open", 4, esqlite_open},
|
{"open", 4, esqlite_open},
|
||||||
{"exec", 4, esqlite_exec},
|
{"exec", 4, esqlite_exec},
|
||||||
{"prepare", 4, esqlite_prepare},
|
{"prepare", 4, esqlite_prepare},
|
||||||
|
{"insert", 4, esqlite_insert},
|
||||||
{"step", 3, esqlite_step},
|
{"step", 3, esqlite_step},
|
||||||
// TODO: {"esqlite_bind", 3, esqlite_bind_named},
|
// TODO: {"esqlite_bind", 3, esqlite_bind_named},
|
||||||
{"bind", 4, esqlite_bind},
|
{"bind", 4, esqlite_bind},
|
||||||
|
|||||||
@@ -23,6 +23,7 @@
|
|||||||
%% higher-level export
|
%% higher-level export
|
||||||
-export([open/1, open/2,
|
-export([open/1, open/2,
|
||||||
exec/2, exec/3,
|
exec/2, exec/3,
|
||||||
|
insert/2,
|
||||||
prepare/2, prepare/3,
|
prepare/2, prepare/3,
|
||||||
step/1, step/2,
|
step/1, step/2,
|
||||||
bind/2, bind/3,
|
bind/2, bind/3,
|
||||||
@@ -199,6 +200,20 @@ exec(Sql, {connection, _Ref, Connection}, Timeout) ->
|
|||||||
ok = esqlite3_nif:exec(Connection, Ref, self(), Sql),
|
ok = esqlite3_nif:exec(Connection, Ref, self(), Sql),
|
||||||
receive_answer(Ref, Timeout).
|
receive_answer(Ref, Timeout).
|
||||||
|
|
||||||
|
%% @doc Insert records, returns the last rowid.
|
||||||
|
%%
|
||||||
|
%% @spec insert(iolist(), connection()) -> {ok, integer()} | {error, error_message()}
|
||||||
|
insert(Sql, Connection) ->
|
||||||
|
insert(Sql, Connection, ?DEFAULT_TIMEOUT).
|
||||||
|
|
||||||
|
%% @doc Insert
|
||||||
|
%%
|
||||||
|
%% @spec insert(iolist(), connection(), timeout()) -> {ok, integer()} | {error, error_message()}
|
||||||
|
insert(Sql, {connection, _Ref, Connection}, Timeout) ->
|
||||||
|
Ref = make_ref(),
|
||||||
|
ok = esqlite3_nif:insert(Connection, Ref, self(), Sql),
|
||||||
|
receive_answer(Ref, Timeout).
|
||||||
|
|
||||||
%% @doc Prepare a statement
|
%% @doc Prepare a statement
|
||||||
%%
|
%%
|
||||||
%% @spec prepare(iolist(), connection()) -> {ok, prepared_statement()} | {error, error_message()}
|
%% @spec prepare(iolist(), connection()) -> {ok, prepared_statement()} | {error, error_message()}
|
||||||
|
|||||||
@@ -21,15 +21,16 @@
|
|||||||
-author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>").
|
-author("Maas-Maarten Zeeman <mmzeeman@xs4all.nl>").
|
||||||
|
|
||||||
%% low-level exports
|
%% low-level exports
|
||||||
-export([start/0,
|
-export([start/0,
|
||||||
open/4,
|
open/4,
|
||||||
exec/4,
|
exec/4,
|
||||||
prepare/4,
|
insert/4,
|
||||||
step/3,
|
prepare/4,
|
||||||
finalize/3,
|
step/3,
|
||||||
bind/4,
|
finalize/3,
|
||||||
column_names/3,
|
bind/4,
|
||||||
close/3
|
column_names/3,
|
||||||
|
close/3
|
||||||
]).
|
]).
|
||||||
|
|
||||||
-on_load(init/0).
|
-on_load(init/0).
|
||||||
@@ -37,9 +38,9 @@
|
|||||||
init() ->
|
init() ->
|
||||||
NifName = "esqlite3_nif",
|
NifName = "esqlite3_nif",
|
||||||
NifFileName = case code:priv_dir(esqlite) of
|
NifFileName = case code:priv_dir(esqlite) of
|
||||||
{error, bad_name} -> filename:join("priv", NifName);
|
{error, bad_name} -> filename:join("priv", NifName);
|
||||||
Dir -> filename:join(Dir, NifName)
|
Dir -> filename:join(Dir, NifName)
|
||||||
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.
|
||||||
@@ -105,7 +106,12 @@ column_names(_Stmt, _Ref, _Dest) ->
|
|||||||
close(_Db, _Ref, _Dest) ->
|
close(_Db, _Ref, _Dest) ->
|
||||||
exit(nif_library_not_loaded).
|
exit(nif_library_not_loaded).
|
||||||
|
|
||||||
|
|
||||||
|
%% @doc Insert record
|
||||||
|
%%
|
||||||
|
%% @spec insert(connection(), Ref::reference(), Dest::pid(), string()) -> {ok, integer()} | {error, message()}
|
||||||
|
insert(_Db, _Ref, _Dest, _Sql) ->
|
||||||
|
exit(nif_library_not_loaded).
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user