Commit 3ae6fb96 authored by Barton E. Schaefer's avatar Barton E. Schaefer

34446: add "ztie -r" and "zuntie -u", update documentation

parent 061dc888
2015-02-01 Barton E. Schaefer <schaefer@zsh.org>
* 34446: Doc/Zsh/mod_db_gdbm.yo, Src/Modules/db_gdbm.c: add
"ztie -r" and "zuntie -u", update documentation for this and
for 34430,34439.
2015-02-01 Daniel Shahaf <d.s@daniel.shahaf.name>
* 34411: Completion/Unix/Command/_hg: _hg completion: Complete
......
......@@ -11,17 +11,41 @@ The builtins in this module are:
startitem()
findex(ztie)
cindex(tied array, creating)
item(tt(ztie -d db/gdbm -f) var(filename) var(arrayname))(
cindex(database tied array, creating)
item(tt(ztie -d db/gdbm -f) var(filename) [ tt(-r) ] var(arrayname))(
Open the GDBM database identified by var(filename) and, if successful,
create the associative array var(arrayname) linked to the file. Note
that var(arrayname) must be unset at the time tt(ztie) is called, and
is always created as a global parameter (as if with `tt(typeset -g)').
create the associative array var(arrayname) linked to the file. To create
a local tied array, the parameter must first be declared, so commands
similar to the following would be executed inside a function scope:
example(local -A sampledb
ztie -d db/gdbm -f sample.gdbm sampledb)
The tt(-r) option opens the database file for reading only, creating a
parameter with the readonly attribute. Without this option, using
`tt(ztie)' on a file for which the user does not have write permission is
an error. If writable, the database is opened synchronously so fields
changed in var(arrayname) are immediately written to var(filename).
Changes to the file modes var(filename) after it has been opened do not
alter the state of var(arrayname), but `tt(typeset -r) var(arrayname)'
works as expected.
)
findex(zuntie)
cindex(tied array, destroying)
item(tt(zuntie) var(arrayname) ...)(
cindex(database tied array, destroying)
item(tt(zuntie) [ tt(-u) ] var(arrayname) ...)(
Close the GDBM database associated with each var(arrayname) and then
unset the variable.
unset the parameter. The tt(-u) option forces an unset of parameters
made readonly with `tt(ztie -r)'.
This happens automatically if the parameter is explicitly unset or its
local scope (function) ends. Note that a readonly parameter may not be
explicitly unset, so the only way to unset a global parameter created with
`tt(ztie -r)' is to use `tt(zuntie -u)'.
)
enditem()
The fields of an associative array tied to GDBM are neither cached nor
otherwise stored in memory, they are read from or written to the database
on each reference. Thus, for example, the values in a readonly array may
be changed by a second writer of the same database file.
......@@ -48,8 +48,8 @@ static const struct gsu_hash gdbm_hash_gsu =
{ hashgetfn, hashsetfn, gdbmhashunsetfn };
static struct builtin bintab[] = {
BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:", NULL),
BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, NULL, NULL),
BUILTIN("ztie", 0, bin_ztie, 1, -1, 0, "d:f:r", NULL),
BUILTIN("zuntie", 0, bin_zuntie, 1, -1, 0, "u", NULL),
};
/**/
......@@ -58,6 +58,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
{
char *resource_name, *pmname;
GDBM_FILE dbf = NULL;
int read_write = GDBM_SYNC, pmflags = PM_REMOVABLE;
Param tied_param;
if(!OPT_ISSET(ops,'d')) {
......@@ -68,6 +69,12 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
zwarnnam(nam, "you must pass `-f' with a filename", NULL);
return 1;
}
if (OPT_ISSET(ops,'r')) {
read_write |= GDBM_READER;
pmflags |= PM_READONLY;
} else {
read_write |= GDBM_WRCREAT;
}
/* Here should be a lookup of the backend type against
* a registry.
......@@ -79,9 +86,9 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
resource_name = OPT_ARG(ops, 'f');
dbf = gdbm_open(resource_name, 0, GDBM_WRCREAT | GDBM_SYNC, 0666, 0);
dbf = gdbm_open(resource_name, 0, read_write, 0666, 0);
if(!dbf) {
zwarnnam(nam, "error opening database file %s", resource_name);
zwarnnam(nam, "error opening database file %s", resource_name);
return 1;
}
......@@ -101,7 +108,7 @@ bin_ztie(char *nam, char **args, Options ops, UNUSED(int func))
}
}
if (!(tied_param = createspecialhash(pmname, &getgdbmnode, &scangdbmkeys,
PM_REMOVABLE))) {
pmflags))) {
zwarnnam(nam, "cannot create the requested parameter %s", pmname);
gdbm_close(dbf);
return 1;
......@@ -135,6 +142,8 @@ bin_zuntie(char *nam, char **args, Options ops, UNUSED(int func))
}
queue_signals();
if (OPT_ISSET(ops,'u'))
gdbmuntie(pm); /* clear read-only-ness */
if (unsetparam_pm(pm, 0, 1)) {
/* assume already reported */
ret = 1;
......@@ -250,19 +259,30 @@ scangdbmkeys(HashTable ht, ScanFunc func, int flags)
/**/
static void
gdbmhashunsetfn(Param pm, UNUSED(int exp))
gdbmuntie(Param pm)
{
GDBM_FILE dbf = (GDBM_FILE)(pm->u.hash->tmpdata);
HashTable ht = pm->u.hash;
if (!dbf) /* paranoia */
return;
if (dbf) /* paranoia */
gdbm_close(dbf);
gdbm_close(dbf);
pm->u.hash->tmpdata = NULL;
ht->tmpdata = NULL;
/* hash table is now normal, so proceed normally... */
pm->node.flags &= ~PM_SPECIAL;
/* for completeness ... createspecialhash() should have an inverse */
ht->getnode = ht->getnode2 = gethashnode2;
ht->scantab = NULL;
pm->node.flags &= ~(PM_SPECIAL|PM_READONLY);
pm->gsu.h = &stdhash_gsu;
}
/**/
static void
gdbmhashunsetfn(Param pm, UNUSED(int exp))
{
gdbmuntie(pm);
/* hash table is now normal, so proceed normally... */
pm->gsu.h->setfn(pm, NULL);
pm->node.flags |= PM_UNSET;
}
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment