Merge pull request #5 from qingliangcn/master

add insert function to get last insert rowid
This commit is contained in:
Maas-Maarten Zeeman
2013-11-27 11:05:03 -08:00
3 changed files with 89 additions and 14 deletions

View File

@@ -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},

View File

@@ -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()}

View File

@@ -24,6 +24,7 @@
-export([start/0, -export([start/0,
open/4, open/4,
exec/4, exec/4,
insert/4,
prepare/4, prepare/4,
step/3, step/3,
finalize/3, finalize/3,
@@ -106,6 +107,11 @@ 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).