Implemented backu_step

This commit is contained in:
Maas-Maarten Zeeman
2022-01-08 22:19:22 +01:00
parent e635710bda
commit d0cc3b10cc
4 changed files with 73 additions and 6 deletions

View File

@@ -263,6 +263,10 @@ destruct_esqlite_backup(ErlNifEnv *env, void *arg)
{ {
esqlite_backup *backup = (esqlite_backup *) arg; esqlite_backup *backup = (esqlite_backup *) arg;
if(backup->backup) {
sqlite3_backup_finish(backup->backup);
}
backup->backup = NULL; backup->backup = NULL;
} }
@@ -751,7 +755,6 @@ do_backup_init(ErlNifEnv *env, sqlite3 *db, const ERL_NIF_TERM arg)
if(!enif_get_tuple(env, arg, &tuple_arity, &elements)) { if(!enif_get_tuple(env, arg, &tuple_arity, &elements)) {
return make_error_tuple(env, "no_tuple"); return make_error_tuple(env, "no_tuple");
} }
if(tuple_arity != 3) { if(tuple_arity != 3) {
return make_error_tuple(env, "invalid_tuple"); return make_error_tuple(env, "invalid_tuple");
} }
@@ -791,9 +794,46 @@ do_backup_init(ErlNifEnv *env, sqlite3 *db, const ERL_NIF_TERM arg)
} }
static ERL_NIF_TERM static ERL_NIF_TERM
do_backup_step(ErlNifEnv *env, const ERL_NIF_TERM arg) do_backup_step(ErlNifEnv *env, sqlite3 *db, const ERL_NIF_TERM arg)
{ {
return make_atom(env, "todo"); int tuple_arity;
const ERL_NIF_TERM *elements;
esqlite_backup *esqlite_backup;
int n_page = 0;
int rc;
if(db == NULL) {
return make_error_tuple(env, "closed");
}
if(!enif_get_tuple(env, arg, &tuple_arity, &elements)) {
return make_error_tuple(env, "no_tuple");
}
if(tuple_arity != 2) {
return make_error_tuple(env, "invalid_tuple");
}
if(!enif_get_resource(env, elements[0], esqlite_backup_type, (void **) &esqlite_backup)) {
return make_error_tuple(env, "invalid");
}
if(!esqlite_backup->backup) {
return make_error_tuple(env, "backup");
}
if(!enif_get_int(env, elements[1], &n_page)) {
return make_error_tuple(env, "n_page");
}
rc = sqlite3_backup_step(esqlite_backup->backup, n_page);
if(rc == SQLITE_DONE) {
return make_atom(env, "done");
}
if(rc != SQLITE_OK) {
return make_sqlite3_error_tuple(env, rc, db);
}
return make_atom(env, "ok");
} }
static ERL_NIF_TERM static ERL_NIF_TERM
@@ -833,7 +873,18 @@ do_backup_pagecount(ErlNifEnv *env, const ERL_NIF_TERM arg)
static ERL_NIF_TERM static ERL_NIF_TERM
do_backup_finish(ErlNifEnv *env, const ERL_NIF_TERM arg) do_backup_finish(ErlNifEnv *env, const ERL_NIF_TERM arg)
{ {
return make_atom(env, "todo"); esqlite_backup *esqlite_backup;
if(!enif_get_resource(env, arg, esqlite_backup_type, (void **) &esqlite_backup)) {
return make_error_tuple(env, "invalid");
}
if(esqlite_backup->backup) {
(void) sqlite3_backup_finish(esqlite_backup->backup);
esqlite_backup->backup = NULL;
}
return make_atom(env, "ok");
} }
static ERL_NIF_TERM static ERL_NIF_TERM
@@ -884,7 +935,7 @@ evaluate_command(esqlite_command *cmd, esqlite_connection *conn)
case cmd_backup_init: case cmd_backup_init:
return do_backup_init(cmd->env, conn->db, cmd->arg); return do_backup_init(cmd->env, conn->db, cmd->arg);
case cmd_backup_step: case cmd_backup_step:
return do_backup_step(cmd->env, cmd->arg); return do_backup_step(cmd->env, conn->db, cmd->arg);
case cmd_backup_remaining: case cmd_backup_remaining:
return do_backup_remaining(cmd->env, cmd->arg); return do_backup_remaining(cmd->env, cmd->arg);
case cmd_backup_pagecount: case cmd_backup_pagecount:

View File

@@ -39,6 +39,7 @@
backup_init/4, backup_init/5, backup_init/4, backup_init/5,
backup_remaining/1, backup_remaining/2, backup_remaining/1, backup_remaining/2,
backup_pagecount/1, backup_pagecount/2, backup_pagecount/1, backup_pagecount/2,
backup_step/2, backup_step/3,
close/1, close/2, close/1, close/2,
flush/0 flush/0
]). ]).
@@ -554,6 +555,20 @@ backup_init(#connection{raw_connection=Dest}, DestName, #connection{raw_connecti
Error Error
end. end.
%% @doc Do a backup step.
-spec backup_step(backup(), integer()) -> ok | {error, _}.
backup_step(Backup, NPage) ->
backup_step(Backup, NPage, ?DEFAULT_TIMEOUT).
%% @doc Do a backup step.
-spec backup_step(backup(), integer(), timeout()) -> ok | {error, _}.
backup_step(#backup{raw_connection=Conn, raw_backup=Back}, NPage, Timeout) ->
Ref = make_ref(),
ok = esqlite3_nif:backup_step(Conn, Back, NPage, Ref, self()),
receive_answer(Conn, Ref, Timeout).
%% @doc Get the remaining number of pages which need to be backed up. %% @doc Get the remaining number of pages which need to be backed up.
-spec backup_remaining(backup()) -> {ok, pos_integer()} | {error, _}. -spec backup_remaining(backup()) -> {ok, pos_integer()} | {error, _}.
backup_remaining(Backup) -> backup_remaining(Backup) ->

View File

@@ -143,7 +143,7 @@ column_types(_Db, _Stmt, _Ref, _Dest) ->
erlang:nif_error(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).
%% @doc Initialize a backup procedure of a database. %% @doc Initialize a backup procedure of a database.
-spec backup_init(raw_connection(), iodata(), raw_connection(), iodata(), reference(), pid()) -> ok | {error, _}. -spec backup_init(raw_connection(), string(), raw_connection(), string(), reference(), pid()) -> ok | {error, _}.
backup_init(_DestDb, _DestName, _SourceDb, _SourceName, _Ref, _Dest) -> backup_init(_DestDb, _DestName, _SourceDb, _SourceName, _Ref, _Dest) ->
erlang:nif_error(nif_library_not_loaded). erlang:nif_error(nif_library_not_loaded).

View File

@@ -447,6 +447,7 @@ backup_test() ->
{ok, Backup} = esqlite3:backup_init(Dest, "main", Source, "main"), {ok, Backup} = esqlite3:backup_init(Dest, "main", Source, "main"),
{ok, 0} = esqlite3:backup_remaining(Backup), {ok, 0} = esqlite3:backup_remaining(Backup),
{ok, 0} = esqlite3:backup_pagecount(Backup), {ok, 0} = esqlite3:backup_pagecount(Backup),
done = esqlite3:backup_step(Backup, 1),
ok. ok.