Add get changes
This commit is contained in:
@@ -363,6 +363,9 @@ static ErlDrvSSizeT control(
|
|||||||
case CMD_ENABLE_LOAD_EXTENSION:
|
case CMD_ENABLE_LOAD_EXTENSION:
|
||||||
enable_load_extension(drv, buf, (int) len);
|
enable_load_extension(drv, buf, (int) len);
|
||||||
break;
|
break;
|
||||||
|
case CMD_CHANGES:
|
||||||
|
changes(drv, buf, (int) len);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
unknown(drv, buf, (int) len);
|
unknown(drv, buf, (int) len);
|
||||||
}
|
}
|
||||||
@@ -370,6 +373,26 @@ static ErlDrvSSizeT control(
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int changes(sqlite3_drv_t *drv, char *buf, int len) {
|
||||||
|
int changes = sqlite3_changes(drv->db);
|
||||||
|
ErlDrvTermData spec[6];
|
||||||
|
|
||||||
|
spec[0] = ERL_DRV_PORT;
|
||||||
|
spec[1] = driver_mk_port(drv->port);
|
||||||
|
spec[2] = ERL_DRV_UINT;
|
||||||
|
spec[3] = changes;
|
||||||
|
spec[4] = ERL_DRV_TUPLE;
|
||||||
|
spec[5] = 2;
|
||||||
|
|
||||||
|
return
|
||||||
|
#ifdef PRE_R16B
|
||||||
|
driver_output_term(drv->port,
|
||||||
|
#else
|
||||||
|
erl_drv_output_term(spec[1],
|
||||||
|
#endif
|
||||||
|
spec, sizeof(spec) / sizeof(spec[0]));
|
||||||
|
}
|
||||||
|
|
||||||
static int enable_load_extension(sqlite3_drv_t* drv, char *buf, int len) {
|
static int enable_load_extension(sqlite3_drv_t* drv, char *buf, int len) {
|
||||||
#ifdef ERLANG_SQLITE3_LOAD_EXTENSION
|
#ifdef ERLANG_SQLITE3_LOAD_EXTENSION
|
||||||
char enable = buf[0];
|
char enable = buf[0];
|
||||||
|
|||||||
@@ -49,6 +49,7 @@ typedef int ErlDrvSSizeT;
|
|||||||
#define CMD_PREPARED_COLUMNS 11
|
#define CMD_PREPARED_COLUMNS 11
|
||||||
#define CMD_SQL_EXEC_SCRIPT 12
|
#define CMD_SQL_EXEC_SCRIPT 12
|
||||||
#define CMD_ENABLE_LOAD_EXTENSION 13
|
#define CMD_ENABLE_LOAD_EXTENSION 13
|
||||||
|
#define CMD_CHANGES 14
|
||||||
|
|
||||||
typedef struct ptr_list {
|
typedef struct ptr_list {
|
||||||
void *head;
|
void *head;
|
||||||
@@ -118,6 +119,7 @@ static void sql_free_async(void *async_command);
|
|||||||
static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data);
|
static void ready_async(ErlDrvData drv_data, ErlDrvThreadData thread_data);
|
||||||
static int unknown(sqlite3_drv_t *bdb_drv, char *buf, int len);
|
static int unknown(sqlite3_drv_t *bdb_drv, char *buf, int len);
|
||||||
static int enable_load_extension(sqlite3_drv_t *drv, char *buf, int len);
|
static int enable_load_extension(sqlite3_drv_t *drv, char *buf, int len);
|
||||||
|
static int changes(sqlite3_drv_t *drv, char *buf, int len);
|
||||||
|
|
||||||
#if defined(_MSC_VER)
|
#if defined(_MSC_VER)
|
||||||
#pragma warning(default: 4201)
|
#pragma warning(default: 4201)
|
||||||
|
|||||||
@@ -40,6 +40,7 @@
|
|||||||
-export([delete/2, delete/3, delete_timeout/4]).
|
-export([delete/2, delete/3, delete_timeout/4]).
|
||||||
-export([drop_table/1, drop_table/2, drop_table_timeout/3]).
|
-export([drop_table/1, drop_table/2, drop_table_timeout/3]).
|
||||||
-export([vacuum/0, vacuum/1, vacuum_timeout/2]).
|
-export([vacuum/0, vacuum/1, vacuum_timeout/2]).
|
||||||
|
-export([changes/1]).
|
||||||
|
|
||||||
%% -export([create_function/3]).
|
%% -export([create_function/3]).
|
||||||
|
|
||||||
@@ -164,6 +165,18 @@ stop() ->
|
|||||||
enable_load_extension(Db, Value) ->
|
enable_load_extension(Db, Value) ->
|
||||||
gen_server:call(Db, {enable_load_extension, Value}).
|
gen_server:call(Db, {enable_load_extension, Value}).
|
||||||
|
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
%% @doc
|
||||||
|
%% Get affected rows.
|
||||||
|
%% @end
|
||||||
|
%%--------------------------------------------------------------------
|
||||||
|
|
||||||
|
changes(Db) ->
|
||||||
|
gen_server:call(Db, changes).
|
||||||
|
|
||||||
|
changes(Db, Timeout) ->
|
||||||
|
gen_server:call(Db, changes, Timeout).
|
||||||
|
|
||||||
%%--------------------------------------------------------------------
|
%%--------------------------------------------------------------------
|
||||||
%% @doc
|
%% @doc
|
||||||
%% Executes the Sql statement directly.
|
%% Executes the Sql statement directly.
|
||||||
@@ -974,6 +987,9 @@ handle_call({enable_load_extension, _Value} = Payload, _From, State = #state{por
|
|||||||
Port, refs = _Refs}) ->
|
Port, refs = _Refs}) ->
|
||||||
Reply = exec(Port, Payload),
|
Reply = exec(Port, Payload),
|
||||||
{reply, Reply, State};
|
{reply, Reply, State};
|
||||||
|
handle_call(changes = Payload, _From, State = #state{port = Port, refs = _Refs}) ->
|
||||||
|
Reply = exec(Port, Payload),
|
||||||
|
{reply, Reply, State};
|
||||||
handle_call({Cmd, Ref}, _From, State = #state{port = Port, refs = Refs}) ->
|
handle_call({Cmd, Ref}, _From, State = #state{port = Port, refs = Refs}) ->
|
||||||
Reply = case dict:find(Ref, Refs) of
|
Reply = case dict:find(Ref, Refs) of
|
||||||
{ok, Index} ->
|
{ok, Index} ->
|
||||||
@@ -1074,6 +1090,7 @@ get_priv_dir() ->
|
|||||||
-define(PREPARED_COLUMNS, 11).
|
-define(PREPARED_COLUMNS, 11).
|
||||||
-define(SQL_EXEC_SCRIPT, 12).
|
-define(SQL_EXEC_SCRIPT, 12).
|
||||||
-define(ENABLE_LOAD_EXTENSION, 13).
|
-define(ENABLE_LOAD_EXTENSION, 13).
|
||||||
|
-define(CHANGES, 14).
|
||||||
|
|
||||||
create_port_cmd(DbFile) ->
|
create_port_cmd(DbFile) ->
|
||||||
atom_to_list(?DRIVER_NAME) ++ " " ++ DbFile.
|
atom_to_list(?DRIVER_NAME) ++ " " ++ DbFile.
|
||||||
@@ -1126,6 +1143,9 @@ exec(Port, {enable_load_extension, Value}) ->
|
|||||||
end,
|
end,
|
||||||
port_control(Port, ?ENABLE_LOAD_EXTENSION, <<Payload>>),
|
port_control(Port, ?ENABLE_LOAD_EXTENSION, <<Payload>>),
|
||||||
wait_result(Port);
|
wait_result(Port);
|
||||||
|
exec(Port, changes) ->
|
||||||
|
port_control(Port, ?CHANGES, <<"">>),
|
||||||
|
wait_result(Port);
|
||||||
exec(Port, {Cmd, Index}) when is_integer(Index) ->
|
exec(Port, {Cmd, Index}) when is_integer(Index) ->
|
||||||
CmdCode = case Cmd of
|
CmdCode = case Cmd of
|
||||||
next -> ?PREPARED_STEP;
|
next -> ?PREPARED_STEP;
|
||||||
|
|||||||
2
test.erl
2
test.erl
@@ -8,9 +8,11 @@ test() ->
|
|||||||
sqlite3:open(ct),
|
sqlite3:open(ct),
|
||||||
sqlite3:create_table(ct, user, [{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}]),
|
sqlite3:create_table(ct, user, [{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}]),
|
||||||
[user] = sqlite3:list_tables(ct),
|
[user] = sqlite3:list_tables(ct),
|
||||||
|
0 = sqlite3:changes(ct),
|
||||||
[{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}] = sqlite3:table_info(ct, user),
|
[{id, integer, [primary_key]}, {name, text}, {age, integer}, {wage, integer}] = sqlite3:table_info(ct, user),
|
||||||
{rowid, Id1} = sqlite3:write(ct, user, [{name, "abby"}, {age, 20}, {wage, 2000}]),
|
{rowid, Id1} = sqlite3:write(ct, user, [{name, "abby"}, {age, 20}, {wage, 2000}]),
|
||||||
Id1 = 1,
|
Id1 = 1,
|
||||||
|
1 = sqlite3:changes(ct),
|
||||||
{rowid, Id2} = sqlite3:write(ct, user, [{name, "marge"}, {age, 30}, {wage, 2000}]),
|
{rowid, Id2} = sqlite3:write(ct, user, [{name, "marge"}, {age, 30}, {wage, 2000}]),
|
||||||
Id2 = 2,
|
Id2 = 2,
|
||||||
[{columns, Columns}, {rows, Rows1}] = sqlite3:sql_exec(ct, "select * from user;"),
|
[{columns, Columns}, {rows, Rows1}] = sqlite3:sql_exec(ct, "select * from user;"),
|
||||||
|
|||||||
@@ -53,7 +53,8 @@ all_test_() ->
|
|||||||
?FuncTest(large_offset),
|
?FuncTest(large_offset),
|
||||||
?FuncTest(issue23),
|
?FuncTest(issue23),
|
||||||
?FuncTest(issue13),
|
?FuncTest(issue13),
|
||||||
?FuncTest(enable_load_extension)]}.
|
?FuncTest(enable_load_extension),
|
||||||
|
?FuncTest(changes)]}.
|
||||||
|
|
||||||
anonymous_test() ->
|
anonymous_test() ->
|
||||||
{ok, Pid} = sqlite3:open(anonymous, []),
|
{ok, Pid} = sqlite3:open(anonymous, []),
|
||||||
@@ -349,6 +350,20 @@ issue13() ->
|
|||||||
enable_load_extension() ->
|
enable_load_extension() ->
|
||||||
?assertEqual(ok, sqlite3:enable_load_extension(ct, 1)).
|
?assertEqual(ok, sqlite3:enable_load_extension(ct, 1)).
|
||||||
|
|
||||||
|
changes() ->
|
||||||
|
sqlite3:open(changes, [in_memory]),
|
||||||
|
sqlite3:sql_exec(changes, "CREATE TABLE person(id INTEGER);"),
|
||||||
|
?assertEqual(0, sqlite3:changes(changes)),
|
||||||
|
{rowid, _} = sqlite3:sql_exec(changes, "INSERT INTO person (id) VALUES (1)"),
|
||||||
|
{rowid, _} = sqlite3:sql_exec(changes, "INSERT INTO person (id) VALUES (2)"),
|
||||||
|
{rowid, _} = sqlite3:sql_exec(changes, "INSERT INTO person (id) VALUES (3)"),
|
||||||
|
{rowid, _} = sqlite3:sql_exec(changes, "INSERT INTO person (id) VALUES (4)"),
|
||||||
|
{rowid, _} = sqlite3:sql_exec(changes, "INSERT INTO person (id) VALUES (5)"),
|
||||||
|
?assertEqual(1, sqlite3:changes(changes)),
|
||||||
|
ok = sqlite3:sql_exec(changes, "UPDATE person SET id = 10"),
|
||||||
|
?assertEqual(5, sqlite3:changes(changes)),
|
||||||
|
sqlite3:close(changes).
|
||||||
|
|
||||||
issue23() ->
|
issue23() ->
|
||||||
sqlite3:open(issue23, [in_memory]),
|
sqlite3:open(issue23, [in_memory]),
|
||||||
ok = sqlite3:create_table(issue23, issue23, [{issue23, integer}]),
|
ok = sqlite3:create_table(issue23, issue23, [{issue23, integer}]),
|
||||||
|
|||||||
Reference in New Issue
Block a user