From f01e0efc2d2b664bd515a49954f6fd2f46e2733e Mon Sep 17 00:00:00 2001 From: Leonid Yuriev Date: Wed, 10 Mar 2021 14:43:49 +0300 Subject: [PATCH] mdbx-tools: add `mdbx_drop` tool. Change-Id: Ib7b32668c13fcef5951ff7250df57b3263e14d69 --- .gitignore | 1 + CMakeLists.txt | 4 +- ChangeLog.md | 1 + GNUmakefile | 4 +- src/man1/mdbx_chk.1 | 1 + src/man1/mdbx_copy.1 | 1 + src/man1/mdbx_drop.1 | 48 +++++++++++ src/man1/mdbx_dump.1 | 1 + src/man1/mdbx_load.1 | 1 + src/man1/mdbx_stat.1 | 1 + src/mdbx_drop.c | 187 +++++++++++++++++++++++++++++++++++++++++++ 11 files changed, 247 insertions(+), 3 deletions(-) create mode 100644 src/man1/mdbx_drop.1 create mode 100644 src/mdbx_drop.c diff --git a/.gitignore b/.gitignore index e407d9c4..52ab2dbb 100644 --- a/.gitignore +++ b/.gitignore @@ -22,6 +22,7 @@ mdbx_example libmdbx.creator.user mdbx_chk mdbx_copy +mdbx_drop mdbx_dump mdbx_load mdbx_stat diff --git a/CMakeLists.txt b/CMakeLists.txt index 0556d6ba..e8746421 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -648,7 +648,7 @@ if(MDBX_BUILD_TOOLS) set(WINGETOPT_SRC "") endif() - foreach(TOOL mdbx_chk mdbx_copy mdbx_stat mdbx_dump mdbx_load) + foreach(TOOL mdbx_chk mdbx_copy mdbx_stat mdbx_dump mdbx_load mdbx_drop) add_executable(${TOOL} mdbx.h ${MDBX_SOURCE_DIR}/${TOOL}.c ${WINGETOPT_SRC}) if(MDBX_C_STANDARD) set_target_properties(${TOOL} PROPERTIES @@ -704,6 +704,7 @@ if(MDBX_BUILD_TOOLS) mdbx_copy mdbx_dump mdbx_load + mdbx_drop RUNTIME DESTINATION ${MDBX_TOOLS_INSTALL_DESTINATION} COMPONENT runtime) @@ -718,6 +719,7 @@ if(MDBX_BUILD_TOOLS) "${MDBX_SOURCE_DIR}/man1/mdbx_copy.1" "${MDBX_SOURCE_DIR}/man1/mdbx_dump.1" "${MDBX_SOURCE_DIR}/man1/mdbx_load.1" + "${MDBX_SOURCE_DIR}/man1/mdbx_drop.1" DESTINATION ${MDBX_MAN_INSTALL_DESTINATION} COMPONENT doc) endif() diff --git a/ChangeLog.md b/ChangeLog.md index 9f54a39f..7bfe93e6 100644 --- a/ChangeLog.md +++ b/ChangeLog.md @@ -27,6 +27,7 @@ New features: of grow step and shrink threshold when huge ones (https://github.com/erthink/libmdbx/issues/166). To minimize the impact on compatibility, only the odd values inside the upper half of the range (i.e. 32769..65533) are used for the new representation. + - Added the `mdbx_drop` similar to LMDB command-line tool to purge or delete (sub)database(s). Fixes: diff --git a/GNUmakefile b/GNUmakefile index de4488db..ec9ccf8b 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -57,8 +57,8 @@ SO_SUFFIX := $(shell $(uname2sosuffix)) HEADERS := mdbx.h mdbx.h++ LIBRARIES := libmdbx.a libmdbx.$(SO_SUFFIX) -TOOLS := mdbx_stat mdbx_copy mdbx_dump mdbx_load mdbx_chk -MANPAGES := mdbx_stat.1 mdbx_copy.1 mdbx_dump.1 mdbx_load.1 mdbx_chk.1 +TOOLS := mdbx_stat mdbx_copy mdbx_dump mdbx_load mdbx_chk mdbx_drop +MANPAGES := mdbx_stat.1 mdbx_copy.1 mdbx_dump.1 mdbx_load.1 mdbx_chk.1 mdbx_drop.1 .PHONY: mdbx all install clean diff --git a/src/man1/mdbx_chk.1 b/src/man1/mdbx_chk.1 index 8fb92167..5115fc71 100644 --- a/src/man1/mdbx_chk.1 +++ b/src/man1/mdbx_chk.1 @@ -94,5 +94,6 @@ if no quiet mode was requested. .BR mdbx_copy (1), .BR mdbx_dump (1), .BR mdbx_load (1) +.BR mdbx_drop (1) .SH AUTHOR Leonid Yuriev diff --git a/src/man1/mdbx_copy.1 b/src/man1/mdbx_copy.1 index 1e357cf5..08ffc822 100644 --- a/src/man1/mdbx_copy.1 +++ b/src/man1/mdbx_copy.1 @@ -62,6 +62,7 @@ free during copying cannot be reused until the copy is done. .BR mdbx_chk (1), .BR mdbx_stat (1), .BR mdbx_load (1) +.BR mdbx_drop (1) .SH AUTHOR Howard Chu of Symas Corporation , Leonid Yuriev diff --git a/src/man1/mdbx_drop.1 b/src/man1/mdbx_drop.1 new file mode 100644 index 00000000..0e4effb4 --- /dev/null +++ b/src/man1/mdbx_drop.1 @@ -0,0 +1,48 @@ +.\" Copyright 2021 Leonid Yuriev . +.\" Copyright 2014-2021 Howard Chu, Symas Corp. All Rights Reserved. +.\" Copying restrictions apply. See COPYRIGHT/LICENSE. +.TH MDBX_DROP 1 "2021-02-02" "MDBX 0.9.3" +.SH NAME +mdbx_drop \- MDBX database delete tool +.SH SYNOPSIS +.B mdbx_drop +[\c +.BR \-V ] +[\c +.BR \-d ] +[\c +.BI \-s \ subdb\fR] +[\c +.BR \-n ] +.BR \ dbpath +.SH DESCRIPTION +The +.B mdbx_drop +utility empties or deletes a database in the specified +environment. +.SH OPTIONS +.TP +.BR \-V +Write the library version number to the standard output, and exit. +.TP +.BR \-d +Delete the specified database, don't just empty it. +.TP +.BR \-s \ subdb +Operate on a specific subdatabase. If no database is specified, only the main database is dropped. +.TP +.BR \-n +Dump an MDBX database which does not use subdirectories. +This is legacy option. For now MDBX handles this automatically. + +.SH DIAGNOSTICS +Exit status is zero if no errors occur. +Errors result in a non-zero exit status and +a diagnostic message being written to standard error. +.SH "SEE ALSO" +.BR mdbx_load (1), +.BR mdbx_copy (1), +.BR mdbx_chk (1), +.BR mdbx_stat (1) +.SH AUTHOR +Howard Chu of Symas Corporation diff --git a/src/man1/mdbx_dump.1 b/src/man1/mdbx_dump.1 index 5c5e1f97..b7c56e19 100644 --- a/src/man1/mdbx_dump.1 +++ b/src/man1/mdbx_dump.1 @@ -88,6 +88,7 @@ utility to load the database using the correct comparison functions. .BR mdbx_copy (1), .BR mdbx_chk (1), .BR mdbx_stat (1) +.BR mdbx_drop (1) .SH AUTHOR Howard Chu of Symas Corporation , Leonid Yuriev diff --git a/src/man1/mdbx_load.1 b/src/man1/mdbx_load.1 index 90c1ff8e..c9690bda 100644 --- a/src/man1/mdbx_load.1 +++ b/src/man1/mdbx_load.1 @@ -99,6 +99,7 @@ a diagnostic message being written to standard error. .BR mdbx_chk (1), .BR mdbx_stat (1), .BR mdbx_copy (1) +.BR mdbx_drop (1) .SH AUTHOR Howard Chu of Symas Corporation , Leonid Yuriev diff --git a/src/man1/mdbx_stat.1 b/src/man1/mdbx_stat.1 index 6e5fa51d..d28f0d15 100644 --- a/src/man1/mdbx_stat.1 +++ b/src/man1/mdbx_stat.1 @@ -73,6 +73,7 @@ a diagnostic message being written to standard error. .BR mdbx_copy (1), .BR mdbx_dump (1), .BR mdbx_load (1) +.BR mdbx_drop (1) .SH AUTHOR Howard Chu of Symas Corporation , Leonid Yuriev diff --git a/src/mdbx_drop.c b/src/mdbx_drop.c new file mode 100644 index 00000000..258fdf0f --- /dev/null +++ b/src/mdbx_drop.c @@ -0,0 +1,187 @@ +/* mdbx_drop.c - memory-mapped database delete tool */ + +/* + * Copyright 2021 Leonid Yuriev + * and other libmdbx authors: please see AUTHORS file. + * + * Copyright 2016-2021 Howard Chu, Symas Corp. + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted only as authorized by the OpenLDAP + * Public License. + * + * A copy of this license is available in the file LICENSE in the + * top-level directory of the distribution or, alternatively, at + * . */ + +#ifdef _MSC_VER +#if _MSC_VER > 1800 +#pragma warning(disable : 4464) /* relative include path contains '..' */ +#endif +#pragma warning(disable : 4996) /* The POSIX name is deprecated... */ +#endif /* _MSC_VER (warnings) */ + +#define MDBX_TOOLS /* Avoid using internal mdbx_assert() */ +#include "internals.h" + +#include + +#if defined(_WIN32) || defined(_WIN64) +#include "wingetopt.h" + +static volatile BOOL user_break; +static BOOL WINAPI ConsoleBreakHandlerRoutine(DWORD dwCtrlType) { + (void)dwCtrlType; + user_break = true; + return true; +} + +#else /* WINDOWS */ + +static volatile sig_atomic_t user_break; +static void signal_handler(int sig) { + (void)sig; + user_break = 1; +} + +#endif /* !WINDOWS */ + +static char *prog; +bool quiet = false; +static void usage(void) { + fprintf(stderr, "usage: %s [-V] [-q] [-d] [-s name] dbpath\n", prog); + exit(EXIT_FAILURE); + fprintf(stderr, + "usage: %s " + "[-V] [-q] [-a] [-f file] [-s name] [-N] [-p] [-T] [-r] [-n] dbpath\n" + " -V\t\tprint version and exit\n" + " -q\t\tbe quiet\n" + " -d\t\tdelete the specified database, don't just empty it\n", + prog); + exit(EXIT_FAILURE); +} + +static void error(const char *func, int rc) { + if (!quiet) + fprintf(stderr, "%s: %s() error %d %s\n", prog, func, rc, + mdbx_strerror(rc)); +} + +int main(int argc, char *argv[]) { + int i, rc; + MDBX_env *env; + MDBX_txn *txn; + MDBX_dbi dbi; + char *envname = nullptr; + char *subname = nullptr; + int envflags = MDBX_ACCEDE; + bool delete = false; + + prog = argv[0]; + if (argc < 2) + usage(); + + /* -d: delete the db, don't just empty it + * -s: drop the named subDB + * -V: print version and exit + * (default) empty the main DB */ + while ((i = getopt(argc, argv, "ds:nV")) != EOF) { + switch (i) { + case 'V': + printf("mdbx_drop version %d.%d.%d.%d\n" + " - source: %s %s, commit %s, tree %s\n" + " - anchor: %s\n" + " - build: %s for %s by %s\n" + " - flags: %s\n" + " - options: %s\n", + mdbx_version.major, mdbx_version.minor, mdbx_version.release, + mdbx_version.revision, mdbx_version.git.describe, + mdbx_version.git.datetime, mdbx_version.git.commit, + mdbx_version.git.tree, mdbx_sourcery_anchor, mdbx_build.datetime, + mdbx_build.target, mdbx_build.compiler, mdbx_build.flags, + mdbx_build.options); + return EXIT_SUCCESS; + case 'd': + delete = true; + break; + case 'n': + envflags |= MDBX_NOSUBDIR; + break; + case 's': + subname = optarg; + break; + default: + usage(); + } + } + + if (optind != argc - 1) + usage(); + +#if defined(_WIN32) || defined(_WIN64) + SetConsoleCtrlHandler(ConsoleBreakHandlerRoutine, true); +#else +#ifdef SIGPIPE + signal(SIGPIPE, signal_handler); +#endif +#ifdef SIGHUP + signal(SIGHUP, signal_handler); +#endif + signal(SIGINT, signal_handler); + signal(SIGTERM, signal_handler); +#endif /* !WINDOWS */ + + envname = argv[optind]; + if (!quiet) + printf("mdbx_drop %s (%s, T-%s)\nRunning for %s/%s...\n", + mdbx_version.git.describe, mdbx_version.git.datetime, + mdbx_version.git.tree, envname, subname ? subname : "@MAIN"); + fflush(nullptr); + + rc = mdbx_env_create(&env); + if (rc) { + error("mdbx_env_create", rc); + return EXIT_FAILURE; + } + + mdbx_env_set_maxdbs(env, 2); + + rc = mdbx_env_open(env, envname, envflags, 0664); + if (rc) { + error("mdbx_env_open", rc); + goto env_close; + } + + rc = mdbx_txn_begin(env, NULL, 0, &txn); + if (rc) { + error("mdbx_txn_begin", rc); + goto env_close; + } + + rc = mdbx_dbi_open(txn, subname, 0, &dbi); + if (rc) { + error("mdbx_open failed", rc); + goto txn_abort; + } + + rc = mdbx_drop(txn, dbi, delete); + if (rc) { + error("mdbx_drop failed", rc); + goto txn_abort; + } + rc = mdbx_txn_commit(txn); + if (rc) { + error("mdbx_txn_commit failed", rc); + goto txn_abort; + } + txn = nullptr; + +txn_abort: + if (txn) + mdbx_txn_abort(txn); +env_close: + mdbx_env_close(env); + + return rc ? EXIT_FAILURE : EXIT_SUCCESS; +}