mirror of
https://github.com/tursodatabase/libsql.git
synced 2025-06-08 13:04:13 +00:00
.cargo
.github
bindings
bottomless
bottomless-cli
docker-compose
docs
libsql
libsql-ffi
libsql-replication
libsql-rusqlite
libsql-server
libsql-shell
libsql-sqlite3
art
autoconf
contrib
crates
doc
ext
async
crr
expert
fts3
fts5
icu
jni
libsql-wasi
lsm1
misc
rbu
rbu.c
rbu1.test
rbu10.test
rbu11.test
rbu12.test
rbu13.test
rbu14.test
rbu3.test
rbu5.test
rbu6.test
rbu7.test
rbu8.test
rbu9.test
rbuA.test
rbuB.test
rbuC.test
rbu_common.tcl
rbubusy.test
rbucollate.test
rbucrash.test
rbucrash2.test
rbudiff.test
rbudor.test
rbuexlock.test
rbuexpr.test
rbufault.test
rbufault2.test
rbufault3.test
rbufault4.test
rbufts.test
rbumisc.test
rbumulti.test
rbupartial.test
rbupass.test
rbuprogress.test
rburename.test
rburesume.test
rbusave.test
rbusplit.test
rbutemplimit.test
rbuvacuum.test
rbuvacuum2.test
rbuvacuum3.test
rbuvacuum4.test
sqlite3rbu.c
sqlite3rbu.h
test_rbu.c
recover
repair
rtree
session
udf
userauth
vwal
wasi
wasm
README.md
mptest
src
test
tool
vsixtest
.gitignore
Dockerfile-wasm-udf
LIBSQL_VERSION
LICENSE.md
Makefile.in
Makefile.linux-gcc
Makefile.msc
README-SQLite.md
VERSION
aclocal.m4
config.guess
config.sub
configure
configure.ac
install-sh
libsql.pc.in
ltmain.sh
magic.txt
main.mk
manifest
manifest.uuid
spec.template
sqlite.pc.in
sqlite3.1
sqlite3.pc.in
sqlite_cfg.h.in
libsql-sys
vendored
xtask
.dockerignore
.env
.gitignore
CODE_OF_CONDUCT.md
Cargo.toml
Dockerfile
Dockerfile.dev
LICENSE.md
README-libsql.md
README.md
docker-entrypoint.sh
fly.toml
rust-toolchain.toml
196 lines
5.9 KiB
C
196 lines
5.9 KiB
C
/*
|
|
** 2014 August 30
|
|
**
|
|
** The author disclaims copyright to this source code. In place of
|
|
** a legal notice, here is a blessing:
|
|
**
|
|
** May you do good and not evil.
|
|
** May you find forgiveness for yourself and forgive others.
|
|
** May you share freely, never taking more than you give.
|
|
**
|
|
*************************************************************************
|
|
**
|
|
** This file contains a command-line application that uses the RBU
|
|
** extension. See the usage() function below for an explanation.
|
|
*/
|
|
|
|
#include "sqlite3rbu.h"
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
/*
|
|
** Print a usage message and exit.
|
|
*/
|
|
void usage(const char *zArgv0){
|
|
fprintf(stderr,
|
|
"Usage: %s ?OPTIONS? TARGET-DB RBU-DB\n"
|
|
"\n"
|
|
"Where options are:\n"
|
|
"\n"
|
|
" -step NSTEP\n"
|
|
" -statstep NSTATSTEP\n"
|
|
" -vacuum\n"
|
|
" -presql SQL\n"
|
|
"\n"
|
|
" If the -vacuum switch is not present, argument RBU-DB must be an RBU\n"
|
|
" database containing an update suitable for target database TARGET-DB.\n"
|
|
" Or, if -vacuum is specified, then TARGET-DB is a database to vacuum using\n"
|
|
" RBU, and RBU-DB is used as the state database for the vacuum (refer to\n"
|
|
" API documentation for details).\n"
|
|
"\n"
|
|
" If NSTEP is set to less than or equal to zero (the default value), this \n"
|
|
" program attempts to perform the entire update or vacuum operation before\n"
|
|
" exiting\n"
|
|
"\n"
|
|
" If NSTEP is greater than zero, then a maximum of NSTEP calls are made\n"
|
|
" to sqlite3rbu_step(). If the RBU update has not been completely applied\n"
|
|
" after the NSTEP'th call is made, the state is saved in the database RBU-DB\n"
|
|
" and the program exits. Subsequent invocations of this (or any other RBU)\n"
|
|
" application will use this state to resume applying the RBU update to the\n"
|
|
" target db.\n"
|
|
"\n"
|
|
, zArgv0);
|
|
exit(1);
|
|
}
|
|
|
|
void report_default_vfs(){
|
|
sqlite3_vfs *pVfs = sqlite3_vfs_find(0);
|
|
fprintf(stdout, "default vfs is \"%s\"\n", pVfs ? pVfs->zName : "NULL");
|
|
}
|
|
|
|
void report_rbu_vfs(sqlite3rbu *pRbu){
|
|
sqlite3 *db = sqlite3rbu_db(pRbu, 0);
|
|
if( db ){
|
|
char *zName = 0;
|
|
sqlite3_file_control(db, "main", SQLITE_FCNTL_VFSNAME, &zName);
|
|
if( zName ){
|
|
fprintf(stdout, "using vfs \"%s\"\n", zName);
|
|
}else{
|
|
fprintf(stdout, "vfs name not available\n");
|
|
}
|
|
sqlite3_free(zName);
|
|
}
|
|
}
|
|
|
|
int main(int argc, char **argv){
|
|
int i;
|
|
const char *zTarget; /* Target database to apply RBU to */
|
|
const char *zRbu; /* Database containing RBU */
|
|
char zBuf[200]; /* Buffer for printf() */
|
|
char *zErrmsg = 0; /* Error message, if any */
|
|
sqlite3rbu *pRbu; /* RBU handle */
|
|
int nStep = 0; /* Maximum number of step() calls */
|
|
int nStatStep = 0; /* Report stats after this many step calls */
|
|
int bVacuum = 0;
|
|
const char *zPreSql = 0;
|
|
int rc = SQLITE_OK;
|
|
sqlite3_int64 nProgress = 0;
|
|
int nArgc = argc-2;
|
|
|
|
if( argc<3 ) usage(argv[0]);
|
|
for(i=1; i<nArgc; i++){
|
|
const char *zArg = argv[i];
|
|
int nArg = strlen(zArg);
|
|
if( nArg>1 && nArg<=8 && 0==memcmp(zArg, "-vacuum", nArg) ){
|
|
bVacuum = 1;
|
|
}else if( nArg>1 && nArg<=7
|
|
&& 0==memcmp(zArg, "-presql", nArg) && i<nArg-1 ){
|
|
i++;
|
|
zPreSql = argv[i];
|
|
}else if( nArg>1 && nArg<=5 && 0==memcmp(zArg, "-step", nArg) && i<nArg-1 ){
|
|
i++;
|
|
nStep = atoi(argv[i]);
|
|
}else if( nArg>1 && nArg<=9
|
|
&& 0==memcmp(zArg, "-statstep", nArg) && i<nArg-1
|
|
){
|
|
i++;
|
|
nStatStep = atoi(argv[i]);
|
|
}else{
|
|
usage(argv[0]);
|
|
}
|
|
}
|
|
|
|
zTarget = argv[argc-2];
|
|
zRbu = argv[argc-1];
|
|
|
|
report_default_vfs();
|
|
|
|
/* Open an RBU handle. A vacuum handle if -vacuum was specified, or a
|
|
** regular RBU update handle otherwise. */
|
|
if( bVacuum ){
|
|
pRbu = sqlite3rbu_vacuum(zTarget, zRbu);
|
|
}else{
|
|
pRbu = sqlite3rbu_open(zTarget, zRbu, 0);
|
|
}
|
|
report_rbu_vfs(pRbu);
|
|
|
|
if( zPreSql && pRbu ){
|
|
sqlite3 *dbMain = sqlite3rbu_db(pRbu, 0);
|
|
rc = sqlite3_exec(dbMain, zPreSql, 0, 0, 0);
|
|
if( rc==SQLITE_OK ){
|
|
sqlite3 *dbRbu = sqlite3rbu_db(pRbu, 1);
|
|
rc = sqlite3_exec(dbRbu, zPreSql, 0, 0, 0);
|
|
}
|
|
}
|
|
|
|
/* If nStep is less than or equal to zero, call
|
|
** sqlite3rbu_step() until either the RBU has been completely applied
|
|
** or an error occurs. Or, if nStep is greater than zero, call
|
|
** sqlite3rbu_step() a maximum of nStep times. */
|
|
if( rc==SQLITE_OK ){
|
|
for(i=0; (nStep<=0 || i<nStep) && sqlite3rbu_step(pRbu)==SQLITE_OK; i++){
|
|
if( nStatStep>0 && (i % nStatStep)==0 ){
|
|
sqlite3_int64 nUsed;
|
|
sqlite3_int64 nHighwater;
|
|
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0);
|
|
fprintf(stdout, "memory used=%lld highwater=%lld", nUsed, nHighwater);
|
|
if( bVacuum==0 ){
|
|
int one;
|
|
int two;
|
|
sqlite3rbu_bp_progress(pRbu, &one, &two);
|
|
fprintf(stdout, " progress=%d/%d\n", one, two);
|
|
}else{
|
|
fprintf(stdout, "\n");
|
|
}
|
|
fflush(stdout);
|
|
}
|
|
}
|
|
nProgress = sqlite3rbu_progress(pRbu);
|
|
rc = sqlite3rbu_close(pRbu, &zErrmsg);
|
|
}
|
|
|
|
/* Let the user know what happened. */
|
|
switch( rc ){
|
|
case SQLITE_OK:
|
|
sqlite3_snprintf(sizeof(zBuf), zBuf,
|
|
"SQLITE_OK: rbu update incomplete (%lld operations so far)\n",
|
|
nProgress
|
|
);
|
|
fprintf(stdout, "%s", zBuf);
|
|
break;
|
|
|
|
case SQLITE_DONE:
|
|
sqlite3_snprintf(sizeof(zBuf), zBuf,
|
|
"SQLITE_DONE: rbu update completed (%lld operations)\n",
|
|
nProgress
|
|
);
|
|
fprintf(stdout, "%s", zBuf);
|
|
break;
|
|
|
|
default:
|
|
fprintf(stderr, "error=%d: %s\n", rc, zErrmsg);
|
|
break;
|
|
}
|
|
|
|
if( nStatStep>0 ){
|
|
sqlite3_int64 nUsed;
|
|
sqlite3_int64 nHighwater;
|
|
sqlite3_status64(SQLITE_STATUS_MEMORY_USED, &nUsed, &nHighwater, 0);
|
|
fprintf(stdout, "memory used=%lld highwater=%lld\n", nUsed, nHighwater);
|
|
}
|
|
|
|
sqlite3_free(zErrmsg);
|
|
return (rc==SQLITE_OK || rc==SQLITE_DONE) ? 0 : 1;
|
|
}
|