summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSergey Poznyakoff <gray@gnu.org>2022-07-01 14:03:22 +0300
committerSergey Poznyakoff <gray@gnu.org>2022-07-01 14:05:19 +0300
commit0591202918948d41e331094b283ff699ab916c54 (patch)
tree11f13df33e71c0d5bf6ed39cc6a8f1f31db1966f
parentd3f504875cb94d2e458e1e233e5ab8b40281fe2b (diff)
downloadgdbm-0591202918948d41e331094b283ff699ab916c54.tar.gz
Fix semantics of gdbm_load -r
Fixes https://puszcza.gnu.org.ua/bugs/index.php?573 * tools/gdbm_load.c: New option: --update (-U) The --replace (-r) option is valid only if used together with --update. * NEWS: Document changes. * doc/gdbm.texi: Document changes.
-rw-r--r--NEWS13
-rw-r--r--doc/gdbm.texi25
-rw-r--r--tools/gdbm_load.c20
3 files changed, 52 insertions, 6 deletions
diff --git a/NEWS b/NEWS
index 16d8d2a..a0d16b1 100644
--- a/NEWS
+++ b/NEWS
@@ -1,9 +1,20 @@
-GNU dbm NEWS -- history of user-visible changes. 2022-02-04
+GNU dbm NEWS -- history of user-visible changes. 2022-07-01
Copyright (C) 1990-2022 Free Software Foundation, Inc.
See the end of file for copying conditions.
Please send gdbm bug reports to <bug-gdbm@gnu.org>.
+
+* New gdbm_load option: --update
+
+The --update (-U) option instructs gdbm_load to update an existing
+database, whose name is supplied by the second argument.
+
+* Fix semantics of gdbm_load -r
+
+The --replace (-r) is valid only when used together with --update.
+
+
Version 1.23, 2022-02-04
* Bucket cache switched from balanced tree to hash table
diff --git a/doc/gdbm.texi b/doc/gdbm.texi
index e34873f..4fa841f 100644
--- a/doc/gdbm.texi
+++ b/doc/gdbm.texi
@@ -3251,6 +3251,8 @@ symmetry). A special code @samp{all} stands for all available error codes.
In boolean context, the @code{true} value is equivalent to @samp{all},
and @code{false} (i.e. variable unset) is equivalent to @samp{-all}.
+
+This variable cannot be set from interactive sessions.
@end deftypevr
@deftypevr {gdbmtool variable} string errormask
@@ -4070,9 +4072,17 @@ must be given as the second argument.
In general, if two arguments are given, the second one is treated as
the name of the database to create, overriding the file name specified
-in the flat file.
+in the flat file. All existing keys will be removed from this
+database prior to loading from the dump. Use the @option{--update}
+(@option{-U}) option if it is not what you wish.
+
+When given the @option{--update} (@option{-U}) option,
+@command{gdbm_load} will update the existing database with the data
+from the dump. It will bail out if the dump contains a key that is
+already present in the database. To silently overwrite existing keys,
+use the @option{--replace} (@option{-r}) option.
-The utility understands the following command line arguments:
+The utility understands the following command line options:
@table @option
@@ -4098,7 +4108,16 @@ Do not restore file meta-data (ownership and mode) from the flat file.
@item -r
@itemx --replace
-Replace existing keys.
+Replace existing keys. This option can be used only together with
+@option{--update} (@option{-U}).
+
+@item -U
+@itemx --update
+Update an existing database. The database name must be given in the
+second argument to @command{gdbm_load}. The key/value pairs from the
+dump file will be added to that database, without removing the
+existing keys. To overwrite the existing keys from the dump file, use
+@option{--update --replace}.
@item -u @var{user}[:@var{group}]
@itemx --user=@var{user}[:@var{group}]
diff --git a/tools/gdbm_load.c b/tools/gdbm_load.c
index b4691c9..5d5e50e 100644
--- a/tools/gdbm_load.c
+++ b/tools/gdbm_load.c
@@ -32,8 +32,9 @@ gid_t owner_gid;
char *parseopt_program_doc = N_("load a GDBM database from a file");
char *parseopt_program_args = N_("FILE [DB_FILE]");
struct gdbm_option optab[] = {
- { 'r', "replace", NULL, N_("replace records in the existing database") },
+ { 'r', "replace", NULL, N_("replace records in the existing database (needs -U)") },
{ 'm', "mode", N_("MODE"), N_("set file mode") },
+ { 'U', "update", NULL, N_("update the existing database") },
{ 'u', "user", N_("NAME|UID[:NAME|GID]"), N_("set file owner") },
{ 'n', "no-meta", NULL, N_("do not attempt to set file meta-data") },
{ 'M', "mmap", NULL, N_("use memory mapping") },
@@ -139,6 +140,10 @@ main (int argc, char **argv)
}
break;
+ case 'U':
+ oflags = (oflags & ~GDBM_OPENMASK) | GDBM_WRCREAT;
+ break;
+
case 'u':
{
size_t len;
@@ -228,13 +233,24 @@ main (int argc, char **argv)
if (argc > 2)
{
- error (_("too many arguments; try `%s -h' for more info"), progname);
+ error (_("too many arguments; try `%s -h' for more info"));
+ exit (EXIT_USAGE);
+ }
+
+ if (replace && (oflags & GDBM_OPENMASK) != GDBM_WRCREAT)
+ {
+ error (_("-r is useless without -U"));
exit (EXIT_USAGE);
}
filename = argv[0];
if (argc == 2)
dbname = argv[1];
+ else if (oflags & GDBM_WRCREAT)
+ {
+ error (_("-U requires DB_FILE to be supplied"));
+ exit (EXIT_USAGE);
+ }
else
dbname = NULL;