Added update hook
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2011 - 2017 Maas-Maarten Zeeman
|
* Copyright 2011 - 2022 Maas-Maarten Zeeman
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -35,6 +35,8 @@ static ErlNifResourceType *esqlite3_backup_type = NULL;
|
|||||||
/* database connection context */
|
/* database connection context */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
sqlite3 *db;
|
sqlite3 *db;
|
||||||
|
|
||||||
|
ErlNifPid *update_hook_pid;
|
||||||
} esqlite3;
|
} esqlite3;
|
||||||
|
|
||||||
/* prepared statement */
|
/* prepared statement */
|
||||||
@@ -279,9 +281,8 @@ make_extended_error_tuple(ErlNifEnv *env, int code) {
|
|||||||
case SQLITE_OK_SYMLINK:
|
case SQLITE_OK_SYMLINK:
|
||||||
/* internal use only */
|
/* internal use only */
|
||||||
return make_two_atom_tuple(env, "ok", "symlink");
|
return make_two_atom_tuple(env, "ok", "symlink");
|
||||||
default:
|
|
||||||
return make_two_atom_tuple(env, "error", enif_make_int(env, code));
|
|
||||||
}
|
}
|
||||||
|
return enif_make_tuple2(env, make_atom(env, "error"), enif_make_int(env, code));
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *
|
static const char *
|
||||||
@@ -335,45 +336,6 @@ destruct_esqlite3_backup(ErlNifEnv *env, void *arg)
|
|||||||
backup->backup = NULL;
|
backup->backup = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void
|
|
||||||
update_callback(void *arg, int sqlite_operation_type, char const *sqlite_database, char const *sqlite_table, sqlite3_int64 sqlite_rowid)
|
|
||||||
{
|
|
||||||
esqlite3 *db = (esqlite3 *)arg;
|
|
||||||
esqlite_command *cmd = NULL;
|
|
||||||
ERL_NIF_TERM type, table, rowid;
|
|
||||||
|
|
||||||
if(db == NULL)
|
|
||||||
return;
|
|
||||||
|
|
||||||
cmd = command_create();
|
|
||||||
if(!cmd)
|
|
||||||
return;
|
|
||||||
|
|
||||||
rowid = enif_make_int64(cmd->env, sqlite_rowid);
|
|
||||||
table = enif_make_string(cmd->env, sqlite_table, ERL_NIF_LATIN1);
|
|
||||||
|
|
||||||
switch(sqlite_operation_type) {
|
|
||||||
case SQLITE_INSERT:
|
|
||||||
type = make_atom(cmd->env, "insert");
|
|
||||||
break;
|
|
||||||
case SQLITE_DELETE:
|
|
||||||
type = make_atom(cmd->env, "delete");
|
|
||||||
break;
|
|
||||||
case SQLITE_UPDATE:
|
|
||||||
type = make_atom(cmd->env, "update");
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
cmd->type = cmd_notification;
|
|
||||||
cmd->arg = enif_make_tuple3(cmd->env, type, table, rowid);
|
|
||||||
|
|
||||||
push_command(cmd->env, db, cmd);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
do_set_update_hook(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
do_set_update_hook(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
||||||
@@ -392,80 +354,6 @@ do_set_update_hook(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
do_exec(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
|
||||||
{
|
|
||||||
ErlNifBinary bin;
|
|
||||||
int rc;
|
|
||||||
ERL_NIF_TERM eos = enif_make_int(env, 0);
|
|
||||||
|
|
||||||
if(!enif_inspect_iolist_as_binary(env, enif_make_list2(env, arg, eos), &bin)) {
|
|
||||||
return make_error_tuple(env, "no_iodata");
|
|
||||||
}
|
|
||||||
|
|
||||||
rc = sqlite3_exec(conn->db, (char *) bin.data, NULL, NULL, NULL);
|
|
||||||
if(rc != SQLITE_OK)
|
|
||||||
return make_sqlite3_error_tuple(env, rc, conn->db);
|
|
||||||
|
|
||||||
return make_atom(env, "ok");
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Nr of changes
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
do_changes(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
|
||||||
{
|
|
||||||
if(!conn->db) {
|
|
||||||
return make_error_tuple(env, "closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_int64 changes = sqlite3_changes64(conn->db);
|
|
||||||
ERL_NIF_TERM changes_term = enif_make_int64(env, changes);
|
|
||||||
|
|
||||||
return make_ok_tuple(env, changes_term);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* insert action
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
do_insert(ErlNifEnv *env, esqlite3 *conn, const ERL_NIF_TERM arg)
|
|
||||||
{
|
|
||||||
ErlNifBinary bin;
|
|
||||||
int rc;
|
|
||||||
ERL_NIF_TERM eos = enif_make_int(env, 0);
|
|
||||||
|
|
||||||
if(!enif_inspect_iolist_as_binary(env, enif_make_list2(env, arg, eos), &bin)) {
|
|
||||||
return make_error_tuple(env, "no_iodata");
|
|
||||||
}
|
|
||||||
|
|
||||||
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_int64(env, last_rowid);
|
|
||||||
return make_ok_tuple(env, last_rowid_term);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Return the last inserted rowid
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
do_last_insert_rowid(ErlNifEnv *env, esqlite3 *conn)
|
|
||||||
{
|
|
||||||
if(!conn->db) {
|
|
||||||
return make_error_tuple(env, "closed");
|
|
||||||
}
|
|
||||||
|
|
||||||
sqlite3_int64 last_rowid = sqlite3_last_insert_rowid(conn->db);
|
|
||||||
ERL_NIF_TERM last_rowid_term = enif_make_int64(env, last_rowid);
|
|
||||||
|
|
||||||
return make_ok_tuple(env, last_rowid_term);
|
|
||||||
}
|
|
||||||
|
|
||||||
*/
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
static int
|
static int
|
||||||
@@ -854,17 +742,92 @@ esqlite_close(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
return enif_make_badarg(env);
|
return enif_make_badarg(env);
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!enif_get_resource(env, argv[0], esqlite3_type, (void **) &conn))
|
if(!enif_get_resource(env, argv[0], esqlite3_type, (void **) &conn)) {
|
||||||
return enif_make_badarg(env);
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
rc = sqlite3_close_v2(conn->db);
|
rc = sqlite3_close_v2(conn->db);
|
||||||
if(rc != SQLITE_OK)
|
if(rc != SQLITE_OK) {
|
||||||
return make_sqlite3_error_tuple(env, rc);
|
return make_sqlite3_error_tuple(env, rc);
|
||||||
|
}
|
||||||
|
|
||||||
conn->db = NULL;
|
conn->db = NULL;
|
||||||
return make_atom(env, "ok");
|
return make_atom(env, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
update_callback(void *arg, int sqlite_operation_type, char const *sqlite_database, char const *sqlite_table, sqlite3_int64 sqlite_rowid)
|
||||||
|
{
|
||||||
|
esqlite3 *conn = (esqlite3 *)arg;
|
||||||
|
|
||||||
|
if(conn == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Create a message environment */
|
||||||
|
ErlNifEnv *msg_env = enif_alloc_env();
|
||||||
|
|
||||||
|
ERL_NIF_TERM type;
|
||||||
|
|
||||||
|
switch(sqlite_operation_type) {
|
||||||
|
case SQLITE_INSERT:
|
||||||
|
type = make_atom(msg_env, "insert");
|
||||||
|
break;
|
||||||
|
case SQLITE_DELETE:
|
||||||
|
type = make_atom(msg_env, "delete");
|
||||||
|
break;
|
||||||
|
case SQLITE_UPDATE:
|
||||||
|
type = make_atom(msg_env, "update");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
ERL_NIF_TERM rowid = enif_make_int64(msg_env, sqlite_rowid);
|
||||||
|
ERL_NIF_TERM database = make_binary(msg_env, sqlite_database, strlen(sqlite_database));
|
||||||
|
ERL_NIF_TERM table = make_binary(msg_env, sqlite_table, strlen(sqlite_table));
|
||||||
|
|
||||||
|
ERL_NIF_TERM msg = enif_make_tuple4(msg_env, type, database, table, rowid);
|
||||||
|
|
||||||
|
if(!enif_send(NULL, &conn->update_hook_pid, msg_env, msg)) {
|
||||||
|
sqlite3_update_hook(conn->db, NULL, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static ERL_NIF_TERM
|
||||||
|
esqlite_set_update_hook(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
|
{
|
||||||
|
esqlite3 *conn;
|
||||||
|
int rc;
|
||||||
|
|
||||||
|
if(argc != 2) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!enif_get_resource(env, argv[0], esqlite3_type, (void **) &conn)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!conn->db) {
|
||||||
|
return make_error_tuple(env, "closed");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(enif_is_atom(env, argv[1])) {
|
||||||
|
/* Assume this is undefined, reset the connection */
|
||||||
|
sqlite3_update_hook(conn->db, NULL, NULL);
|
||||||
|
} else {
|
||||||
|
/* [todo] passing undefined resets the hook? */
|
||||||
|
if(!enif_get_local_pid(env, argv[1], &conn->update_hook_pid)) {
|
||||||
|
return enif_make_badarg(env);
|
||||||
|
}
|
||||||
|
|
||||||
|
sqlite3_update_hook(conn->db, update_callback, conn);
|
||||||
|
}
|
||||||
|
|
||||||
|
return make_atom(env, "ok");
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Exec a sql statement
|
* Exec a sql statement
|
||||||
*/
|
*/
|
||||||
@@ -984,43 +947,6 @@ set_update_hook(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Bind a variable to a prepared statement
|
|
||||||
static ERL_NIF_TERM
|
|
||||||
esqlite_bind(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|
||||||
{
|
|
||||||
esqlite3 *conn;
|
|
||||||
esqlite3_stmt *stmt;
|
|
||||||
esqlite_command *cmd = NULL;
|
|
||||||
ErlNifPid pid;
|
|
||||||
|
|
||||||
if(argc != 5)
|
|
||||||
return enif_make_badarg(env);
|
|
||||||
|
|
||||||
if(!enif_get_resource(env, argv[0], esqlite3_type, (void **) &conn))
|
|
||||||
return enif_make_badarg(env);
|
|
||||||
if(!enif_get_resource(env, argv[1], esqlite3_stmt_type, (void **) &stmt))
|
|
||||||
return enif_make_badarg(env);
|
|
||||||
if(!enif_is_ref(env, argv[2]))
|
|
||||||
return make_error_tuple(env, "invalid_ref");
|
|
||||||
if(!enif_get_local_pid(env, argv[3], &pid))
|
|
||||||
return make_error_tuple(env, "invalid_pid");
|
|
||||||
|
|
||||||
cmd = command_create();
|
|
||||||
if(!cmd)
|
|
||||||
return make_error_tuple(env, "command_create_failed");
|
|
||||||
|
|
||||||
cmd->type = cmd_bind;
|
|
||||||
cmd->ref = enif_make_copy(cmd->env, argv[2]);
|
|
||||||
cmd->pid = pid;
|
|
||||||
cmd->stmt = enif_make_copy(cmd->env, argv[1]);
|
|
||||||
cmd->arg = enif_make_copy(cmd->env, argv[4]);
|
|
||||||
|
|
||||||
return push_command(env, conn, cmd);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Get the column names of the prepared statement.
|
* Get the column names of the prepared statement.
|
||||||
*/
|
*/
|
||||||
@@ -1241,7 +1167,6 @@ esqlite_bind_null(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
|||||||
return make_atom(env, "ok");
|
return make_atom(env, "ok");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static ERL_NIF_TERM
|
static ERL_NIF_TERM
|
||||||
esqlite_step(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
esqlite_step(ErlNifEnv *env, int argc, const ERL_NIF_TERM argv[])
|
||||||
{
|
{
|
||||||
@@ -1607,6 +1532,8 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"open", 1, esqlite_open, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
{"open", 1, esqlite_open, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
||||||
{"close", 1, esqlite_close, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
{"close", 1, esqlite_close, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
||||||
|
|
||||||
|
{"set_update_hook", 2, esqlite_set_update_hook},
|
||||||
|
|
||||||
{"exec", 2, esqlite_exec},
|
{"exec", 2, esqlite_exec},
|
||||||
{"prepare", 3, esqlite_prepare},
|
{"prepare", 3, esqlite_prepare},
|
||||||
|
|
||||||
@@ -1640,7 +1567,6 @@ static ErlNifFunc nif_funcs[] = {
|
|||||||
{"changes", 1, esqlite_changes},
|
{"changes", 1, esqlite_changes},
|
||||||
|
|
||||||
/*
|
/*
|
||||||
{"set_update_hook", 4, set_update_hook},
|
|
||||||
|
|
||||||
{"exec", 4, esqlite_exec, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
{"exec", 4, esqlite_exec, ERL_NIF_DIRTY_JOB_IO_BOUND},
|
||||||
|
|
||||||
|
|||||||
@@ -22,12 +22,13 @@
|
|||||||
open/1, close/1,
|
open/1, close/1,
|
||||||
|
|
||||||
%% db connection functions
|
%% db connection functions
|
||||||
|
|
||||||
|
set_update_hook/2,
|
||||||
|
|
||||||
get_autocommit/1,
|
get_autocommit/1,
|
||||||
last_insert_rowid/1,
|
last_insert_rowid/1,
|
||||||
changes/1,
|
changes/1,
|
||||||
|
|
||||||
% set_update_hook/2, set_update_hook/3,
|
|
||||||
|
|
||||||
exec/2,
|
exec/2,
|
||||||
prepare/2,
|
prepare/2,
|
||||||
prepare/3,
|
prepare/3,
|
||||||
@@ -46,7 +47,6 @@
|
|||||||
step/1,
|
step/1,
|
||||||
reset/1
|
reset/1
|
||||||
|
|
||||||
% insert/2, insert/3,
|
|
||||||
%
|
%
|
||||||
% fetchone/1,
|
% fetchone/1,
|
||||||
% fetchall/1, fetchall/2, fetchall/3,
|
% fetchall/1, fetchall/2, fetchall/3,
|
||||||
@@ -138,27 +138,20 @@ close(#esqlite3{db=Connection}) ->
|
|||||||
esqlite3_nif:close(Connection).
|
esqlite3_nif:close(Connection).
|
||||||
|
|
||||||
|
|
||||||
%%% @doc Subscribe to database notifications. When rows are inserted deleted
|
%% @doc Subscribe to database notifications. When rows are inserted deleted
|
||||||
%%% or updates, the process will receive messages:
|
%% or updates, the process will receive messages:
|
||||||
%%% ```{insert, string(), rowid()}'''
|
%% ```{insert, binary(), binary(), rowid()}'''
|
||||||
%%% When a new row has been inserted.
|
%% When a new row has been inserted.
|
||||||
%%% ```{delete, string(), rowid()}'''
|
%% ```{delete, binary(), binary(), rowid()}'''
|
||||||
%%% When a new row has been deleted.
|
%% When a new row has been deleted.
|
||||||
%%% ```{update, string(), rowid()}'''
|
%% ```{update, binary(), binary(), rowid()}'''
|
||||||
%%% When a row has been updated.
|
%% When a row has been updated.
|
||||||
%%%
|
%%
|
||||||
%-spec set_update_hook(pid(), connection()) -> ok | {error, term()}.
|
-spec set_update_hook(esqlite3(), pid() | undefined) -> ok | {error, term()}.
|
||||||
%set_update_hook(Pid, Connection) ->
|
set_update_hook(#esqlite3{db=Connection}, MaybePid) when is_pid(MaybePid) orelse MaybePid =:= undefined ->
|
||||||
% set_update_hook(Pid, Connection, ?DEFAULT_TIMEOUT).
|
esqlite3_nif:set_update_hook(Connection, MaybePid).
|
||||||
%
|
|
||||||
%%% @doc Same as set_update_hook/2, but with an additional timeout parameter.
|
|
||||||
%%%
|
|
||||||
%-spec set_update_hook(pid(), connection(), timeout()) -> ok | {error, term()}.
|
|
||||||
%set_update_hook(Pid, #connection{raw_connection=RawConnection}, Timeout) ->
|
|
||||||
% Ref = make_ref(),
|
|
||||||
% ok = esqlite3_nif:set_update_hook(RawConnection, Ref, self(), Pid),
|
|
||||||
% receive_answer(RawConnection, Ref, Timeout).
|
|
||||||
%
|
|
||||||
%%%
|
%%%
|
||||||
%%% q
|
%%% q
|
||||||
%%%
|
%%%
|
||||||
@@ -202,7 +195,7 @@ close(#esqlite3{db=Connection}) ->
|
|||||||
%
|
%
|
||||||
%%% @doc Execute statement and return a list with the result of F for each row.
|
%%% @doc Execute statement and return a list with the result of F for each row.
|
||||||
%-spec map(Fun, sql(), connection()) -> list(Type) when
|
%-spec map(Fun, sql(), connection()) -> list(Type) when
|
||||||
%% Fun :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
|
% Fun :: fun((Row) -> Type) | fun((ColumnNames, Row) -> Type),
|
||||||
% Row :: row(),
|
% Row :: row(),
|
||||||
% ColumnNames :: tuple(),
|
% ColumnNames :: tuple(),
|
||||||
% Type :: any().
|
% Type :: any().
|
||||||
@@ -401,7 +394,6 @@ get_autocommit(#esqlite3{db=Connection}) ->
|
|||||||
exec(#esqlite3{db=Connection}, Sql) ->
|
exec(#esqlite3{db=Connection}, Sql) ->
|
||||||
esqlite3_nif:exec(Connection, Sql).
|
esqlite3_nif:exec(Connection, Sql).
|
||||||
|
|
||||||
|
|
||||||
%% @doc Compile a SQL statement. Returns a cached compiled statement which can be used in
|
%% @doc Compile a SQL statement. Returns a cached compiled statement which can be used in
|
||||||
%% queries.
|
%% queries.
|
||||||
%%
|
%%
|
||||||
|
|||||||
@@ -23,10 +23,11 @@
|
|||||||
open/1,
|
open/1,
|
||||||
close/1,
|
close/1,
|
||||||
|
|
||||||
|
set_update_hook/2,
|
||||||
|
|
||||||
get_autocommit/1,
|
get_autocommit/1,
|
||||||
last_insert_rowid/1,
|
last_insert_rowid/1,
|
||||||
changes/1,
|
changes/1,
|
||||||
|
|
||||||
exec/2,
|
exec/2,
|
||||||
prepare/3,
|
prepare/3,
|
||||||
|
|
||||||
@@ -45,7 +46,6 @@
|
|||||||
reset/1,
|
reset/1,
|
||||||
|
|
||||||
interrupt/1
|
interrupt/1
|
||||||
% set_update_hook/4,
|
|
||||||
% exec/4,
|
% exec/4,
|
||||||
% changes/3,
|
% changes/3,
|
||||||
%
|
%
|
||||||
@@ -98,6 +98,16 @@ open(_Filename) ->
|
|||||||
close(_Db) ->
|
close(_Db) ->
|
||||||
erlang:nif_error(nif_library_not_loaded).
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
|
%% @doc Set an update hook
|
||||||
|
%%
|
||||||
|
-spec set_update_hook(Connection, Pid) -> Result
|
||||||
|
when Connection :: esqlite3(),
|
||||||
|
Pid :: pid(),
|
||||||
|
Result :: ok | {error, _}.
|
||||||
|
set_update_hook(_Db, _Pid) ->
|
||||||
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
|
|
||||||
%% @doc Execute a sql statement
|
%% @doc Execute a sql statement
|
||||||
%%
|
%%
|
||||||
-spec exec(Connection, Sql) -> ExecResult
|
-spec exec(Connection, Sql) -> ExecResult
|
||||||
@@ -136,9 +146,6 @@ step(_Statement) ->
|
|||||||
reset(_Statement) ->
|
reset(_Statement) ->
|
||||||
erlang:nif_error(nif_library_not_loaded).
|
erlang:nif_error(nif_library_not_loaded).
|
||||||
|
|
||||||
% -spec set_update_hook((), pid(), pid()) -> ok | {error, _}.
|
|
||||||
%set_update_hook(_Db, _Ref, _Dest, _Pid) ->
|
|
||||||
% erlang:nif_error(nif_library_not_loaded).
|
|
||||||
|
|
||||||
%% @doc Exec the query.
|
%% @doc Exec the query.
|
||||||
%%
|
%%
|
||||||
|
|||||||
@@ -139,17 +139,29 @@ last_insert_rowid_test() ->
|
|||||||
2 = esqlite3:last_insert_rowid(Db),
|
2 = esqlite3:last_insert_rowid(Db),
|
||||||
ok.
|
ok.
|
||||||
|
|
||||||
%update_hook_test() ->
|
update_hook_test() ->
|
||||||
% {ok, Db} = esqlite3:open(":memory:"),
|
{ok, Db} = esqlite3:open(":memory:"),
|
||||||
% ok = esqlite3:set_update_hook(self(), Db),
|
ok = esqlite3:set_update_hook(Db, self()),
|
||||||
% ok = esqlite3:exec("CREATE TABLE test (id INTEGER PRIMARY KEY, val STRING);", Db),
|
|
||||||
% ok = esqlite3:exec("INSERT INTO test (val) VALUES ('this is a test');", Db),
|
ok = esqlite3:exec(Db, "CREATE TABLE test (id INTEGER PRIMARY KEY, val STRING);"),
|
||||||
% ok = receive {insert, "test", 1} -> ok after 150 -> no_message end,
|
ok = esqlite3:exec(Db, "INSERT INTO test (val) VALUES ('this is a test');"),
|
||||||
% ok = esqlite3:exec("UPDATE test SET val = 'a new test' WHERE id = 1;", Db),
|
|
||||||
% ok = receive {update, "test", 1} -> ok after 150 -> no_message end,
|
ok = receive {insert, <<"main">>, <<"test">>, 1} -> ok after 150 -> no_message end,
|
||||||
% ok = esqlite3:exec("DELETE FROM test WHERE id = 1;", Db),
|
|
||||||
% ok = receive {delete, "test", 1} -> ok after 150 -> no_message end,
|
ok = esqlite3:exec(Db, "UPDATE test SET val = 'a new test' WHERE id = 1;"),
|
||||||
% ok.
|
|
||||||
|
ok = receive {update, <<"main">>, <<"test">>, 1} -> ok after 150 -> no_message end,
|
||||||
|
|
||||||
|
ok = esqlite3:exec(Db, "DELETE FROM test WHERE id = 1;"),
|
||||||
|
|
||||||
|
ok = receive {delete, <<"main">>, <<"test">>, 1} -> ok after 150 -> no_message end,
|
||||||
|
|
||||||
|
ok = esqlite3:set_update_hook(Db, undefined),
|
||||||
|
|
||||||
|
ok = esqlite3:exec(Db, "INSERT INTO test (val) VALUES ('this is a test');"),
|
||||||
|
no_message = receive {insert, <<"main">>, <<"test">>, 1} -> ok after 150 -> no_message end,
|
||||||
|
|
||||||
|
ok.
|
||||||
|
|
||||||
simple_query_test() ->
|
simple_query_test() ->
|
||||||
{ok, Db} = esqlite3:open(":memory:"),
|
{ok, Db} = esqlite3:open(":memory:"),
|
||||||
|
|||||||
Reference in New Issue
Block a user