e576bb | 2002-10-11 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #include "global.h"
#include "gdbm_machine.h"
#include "threads.h"
#include "interpret.h"
#include "svalue.h"
#include "stralloc.h"
|
51ef5c | 2002-10-21 | Marcus Comstedt | | #include "module.h"
|
584f6f | 2014-08-16 | Per Hedbor | | #include "array.h"
|
5d4ff7 | 2005-11-16 | Henrik Grubbström (Grubba) | | #include "program.h"
|
440cf9 | 2005-11-16 | Henrik Grubbström (Grubba) | | #include "module_support.h"
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
6dc277 | 2000-07-28 | Fredrik Hübinette (Hubbe) | | #if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #include <gdbm.h>
|
250587 | 2002-09-25 | Marcus Comstedt | | #ifdef _REENTRANT
|
74ea78 | 2016-01-29 | Martin Nilsson | | static PIKE_MUTEX_T gdbm_lock STATIC_MUTEX_INIT;
|
13670c | 2015-05-25 | Martin Nilsson | | #endif
|
250587 | 2002-09-25 | Marcus Comstedt | |
|
6ad237 | 2002-05-11 | Martin Nilsson | | #define sp Pike_sp
|
584f6f | 2014-08-16 | Per Hedbor | | static struct program *iterator;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | struct gdbm_glue
{
GDBM_FILE dbf;
|
584f6f | 2014-08-16 | Per Hedbor | | struct pike_string *iter;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | };
|
39221e | 2000-07-07 | Henrik Grubbström (Grubba) | | #define THIS ((struct gdbm_glue *)(Pike_fp->current_storage))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
be478c | 1997-08-30 | Henrik Grubbström (Grubba) | | static void do_free(void)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
if(THIS->dbf)
{
GDBM_FILE dbf;
dbf=THIS->dbf;
THIS->dbf=0;
THREADS_ALLOW();
mt_lock(& gdbm_lock);
gdbm_close(dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
}
|
584f6f | 2014-08-16 | Per Hedbor | | if(THIS->iter)
{
free_string(THIS->iter);
THIS->iter=0;
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
a080c8 | 2006-03-18 | Henrik Grubbström (Grubba) | |
#ifndef GDBM_SYNC
#define GDBM_SYNC 0
#endif
#ifndef GDBM_NOLOCK
#define GDBM_NOLOCK 0
#endif
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static int fixmods(char *mods)
{
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | int mode = 0;
int flags = GDBM_NOLOCK;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | while(1)
{
switch(*(mods++))
{
case 0:
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | switch(mode) {
default:
case 0x0:
|
13670c | 2015-05-25 | Martin Nilsson | | Pike_error("No mode given for gdbm->open()\n");
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | case 0x1:
return GDBM_READER;
case 0x3:
return GDBM_WRITER | flags;
case 0x7:
return GDBM_WRCREAT | flags;
case 0xf:
return GDBM_NEWDB | flags;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | case 'r': case 'R': mode = 0x1; break;
case 'w': case 'W': mode = 0x3; break;
case 'c': case 'C': mode = 0x7; break;
case 't': case 'T': mode = 0xf; break;
|
a080c8 | 2006-03-18 | Henrik Grubbström (Grubba) | |
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | case 'f': case 'F': flags |= GDBM_FAST; break;
|
a080c8 | 2006-03-18 | Henrik Grubbström (Grubba) | |
case 's': case 'S': flags |= GDBM_SYNC; break;
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | |
case 'l': case 'L': flags &= ~GDBM_NOLOCK; break;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
default:
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | Pike_error("Bad mode flag '%c' in gdbm->open.\n", mods[-1]);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
}
}
|
584f6f | 2014-08-16 | Per Hedbor | | void gdbmmod_fatal(const char *err)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM: %s\n",err);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
fc293f | 2001-10-26 | Martin Nilsson | | |
584f6f | 2014-08-16 | Per Hedbor | | *!
|
2546a5 | 2014-09-20 | Henrik Grubbström (Grubba) | | *! This module provides an interface to the GNU dbm database.
|
584f6f | 2014-08-16 | Per Hedbor | | *!
*! The basic use of GDBM is to store key/data pairs in a data
*! file. Each key must be unique and each key is paired with only one
*! data item.
*!
*! The library provides primitives for storing key/data pairs,
*! searching and retrieving the data by its key and deleting a key
*! along with its data. It also support sequential iteration over all
*! key/data pairs in a database.
*!
*! The @[DB] class also overloads enough operators to make it behave
|
2546a5 | 2014-09-20 | Henrik Grubbström (Grubba) | | *! a lot like a @tt{mapping(string(8bit):string(8bit))@}, you can index it,
|
584f6f | 2014-08-16 | Per Hedbor | | *! assign indices and loop over it using foreach.
*!
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
584f6f | 2014-08-16 | Per Hedbor | | |
fc293f | 2001-10-26 | Martin Nilsson | | */
|
584f6f | 2014-08-16 | Per Hedbor | | |
fc293f | 2001-10-26 | Martin Nilsson | | *!
*! Without arguments, this function does nothing. With one argument it
*! opens the given file as a gdbm database, if this fails for some
*! reason, an error will be generated. If a second argument is present,
*! it specifies how to open the database using one or more of the follow
*! flags in a string:
*!
*! @string
*! @value r
*! Open database for reading
*! @value w
*! Open database for writing
*! @value c
*! Create database if it does not exist
*! @value t
*! Overwrite existing database
*! @value f
*! Fast mode
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | *! @value s
*! Synchronous mode
*! @value l
*! Locking mode
|
fc293f | 2001-10-26 | Martin Nilsson | | *! @endstring
*!
*! The fast mode prevents the database from syncronizing each change
*! in the database immediately. This is dangerous because the database
*! can be left in an unusable state if Pike is terminated abnormally.
*!
|
cbe8c9 | 2003-04-07 | Martin Nilsson | | *! The default mode is @expr{"rwc"@}.
|
fc293f | 2001-10-26 | Martin Nilsson | | *!
*! @note
*! The gdbm manual states that it is important that the database is
*! closed properly. Unfortunately this will not be the case if Pike
*! calls exit() or returns from main(). You should therefore make sure
*! you call close or destruct your gdbm objects when exiting your
|
584f6f | 2014-08-16 | Per Hedbor | | *! program.
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! @[atexit] might be useful.
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! This is very important if the database is used with the 'l' flag.
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_create(INT32 args)
{
struct gdbm_glue *this=THIS;
do_free();
|
584f6f | 2014-08-16 | Per Hedbor | | if(!args)
Pike_error("Need at least one argument to Gdbm.DB, the filename\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | if(args)
{
GDBM_FILE tmp;
struct pike_string *tmp2;
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | int rwmode = GDBM_WRCREAT|GDBM_NOLOCK;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->create()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(args>1)
{
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[1-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 2 to gdbm->create()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
rwmode=fixmods(sp[1-args].u.string->str);
}
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | if (this->dbf) {
do_free();
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | tmp2=sp[-args].u.string;
THREADS_ALLOW();
mt_lock(& gdbm_lock);
tmp=gdbm_open(tmp2->str, 512, rwmode, 00666, gdbmmod_fatal);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
|
39221e | 2000-07-07 | Henrik Grubbström (Grubba) | | if(!Pike_fp->current_object->prog)
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
if(tmp) gdbm_close(tmp);
|
3b11a1 | 2014-11-01 | Arne Goedeke | | Pike_error("Object destructed in gdbm->create()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
87a8f9 | 2003-05-25 | Martin Nilsson | | this->dbf=tmp;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
87a8f9 | 2003-05-25 | Martin Nilsson | | if(!this->dbf)
|
06d37d | 2006-03-18 | Henrik Grubbström (Grubba) | | Pike_error("Failed to open GDBM database: %d: %s.\n",
gdbm_errno, gdbm_strerror(gdbm_errno));
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
}
#define STRING_TO_DATUM(dat, st) dat.dptr=st->str,dat.dsize=st->len;
#define DATUM_TO_STRING(dat) make_shared_binary_string(dat.dptr, dat.dsize)
|
584f6f | 2014-08-16 | Per Hedbor | | |
fc293f | 2001-10-26 | Martin Nilsson | | *!
*! Return the data associated with the key 'key' in the database.
*! If there was no such key in the database, zero is returned.
*/
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_fetch(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->fetch()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->fetch()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_fetch(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
|
584f6f | 2014-08-16 | Per Hedbor | | push_undefined();
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
}
|
87a8f9 | 2003-05-25 | Martin Nilsson | | |
fc293f | 2001-10-26 | Martin Nilsson | | *!
|
87a8f9 | 2003-05-25 | Martin Nilsson | | *! Remove a key from the database. Returns 1 if successful,
*! otherwise 0, e.g. when the item is not present or the
*! database is read only.
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_delete(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key;
int ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->delete()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->delete()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!this->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_delete(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
|
13670c | 2015-05-25 | Martin Nilsson | |
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | pop_n_elems(args);
|
87a8f9 | 2003-05-25 | Martin Nilsson | | push_int( ret==0 );
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
584f6f | 2014-08-16 | Per Hedbor | | |
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! Provides overloading of the @[m_delete] function.
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! Will return the value the key had before it was removed, if any
*!
*! If the key exists but deletion fails (usually due to a read only
*! database) this function will throw an error.
*/
static void gdbmmod_m_delete(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key, ret;
if(TYPEOF(sp[-args]) != T_STRING)
{
push_undefined();
return;
}
if(!this->dbf)
Pike_error("GDBM database not open.\n");
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_fetch(this->dbf, key);
if( ret.dptr )
if( gdbm_delete(this->dbf, key) )
Pike_error("Failed to delete key from database.\n");
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_undefined();
}
}
|
fc293f | 2001-10-26 | Martin Nilsson | | |
584f6f | 2014-08-16 | Per Hedbor | | *!
*! Used together with @[nextkey] the databse can be iterated.
*!
*! @note
*! The database also works as an @[Iterator], and can be used as the
*! first argument to @[foreach].
*!
*! Adding or removing keys will change the iteration order,
*! this can cause keys to be skipped while iterating.
*!
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! @example
*! @code
*! // Write the contents of the database
*! for(key=gdbm->firstkey(); k; k=gdbm->nextkey(k))
*! write(k+":"+gdbm->fetch(k)+"\n");
*! @endcode
*!
*! Or, using foreach
*! @code
*! // Write the contents of the database
*! foreach( db; string key; string value )
*! write(key+":"+value+"\n");
*! @endcode
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_firstkey(INT32 args)
{
struct gdbm_glue *this=THIS;
datum ret;
pop_n_elems(args);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!this->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_firstkey(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_int(0);
}
}
|
584f6f | 2014-08-16 | Per Hedbor | | |
fc293f | 2001-10-26 | Martin Nilsson | | *!
*! This returns the key in database that follows the key 'key' key.
*! This is of course used to iterate over all keys in the database.
*!
|
584f6f | 2014-08-16 | Per Hedbor | | *! @note
*! Changing (adding or removing keys) the database while iterating
*! can cause keys to be skipped.
*!
*! The database also works as an @[Iterator], and can be used as the
*! first argument to @[foreach].
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
fc293f | 2001-10-26 | Martin Nilsson | | *! @example
|
584f6f | 2014-08-16 | Per Hedbor | | *! @code
|
fc293f | 2001-10-26 | Martin Nilsson | | *! // Write the contents of the database
*! for(key=gdbm->firstkey(); k; k=gdbm->nextkey(k))
*! write(k+":"+gdbm->fetch(k)+"\n");
|
584f6f | 2014-08-16 | Per Hedbor | | *! @endcode
*!
*! Or, using foreach
*! @code
*! // Write the contents of the database
*! foreach( db; string key; string value )
*! write(key+":"+value+"\n");
*! @endcode
*!
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_nextkey(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,ret;
if(!args)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->nextkey()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->nextkey()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_nextkey(this->dbf, key);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
if(ret.dptr)
{
push_string(DATUM_TO_STRING(ret));
free(ret.dptr);
}else{
push_int(0);
}
}
|
584f6f | 2014-08-16 | Per Hedbor | | |
fc293f | 2001-10-26 | Martin Nilsson | | *!
*! Associate the contents of 'data' with the key 'key'. If the key 'key'
*! already exists in the database the data for that key will be replaced.
*! If it does not exist it will be added. An error will be generated if
*! the database was not open for writing.
*!
*! @example
*! gdbm[key] = data;
|
178867 | 2007-04-25 | Henrik Grubbström (Grubba) | | *!
*! @returns
*! Returns @[data] on success.
*!
*! @seealso
*! @[store()]
*/
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_store(INT32 args)
{
struct gdbm_glue *this=THIS;
datum key,data;
|
04878b | 2001-01-23 | John W. Pierce | | int method = GDBM_REPLACE;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | int ret;
if(args<2)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Too few arguments to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 1 to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if(TYPEOF(sp[1-args]) != T_STRING)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("Bad argument 2 to gdbm->store()\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
04878b | 2001-01-23 | John W. Pierce | | if (args > 2) {
|
017b57 | 2011-10-28 | Henrik Grubbström (Grubba) | | if (TYPEOF(sp[2-args]) != T_INT) {
|
04878b | 2001-01-23 | John W. Pierce | | Pike_error("Bad argument 3 to gdbm->store()\n");
}
if (sp[2-args].u.integer) {
method = GDBM_INSERT;
}
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf)
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
STRING_TO_DATUM(key, sp[-args].u.string);
STRING_TO_DATUM(data, sp[1-args].u.string);
THREADS_ALLOW();
mt_lock(& gdbm_lock);
|
04878b | 2001-01-23 | John W. Pierce | | ret=gdbm_store(this->dbf, key, data, method);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
|
04878b | 2001-01-23 | John W. Pierce | | if(ret == -1) {
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | Pike_error("GDBM database not open for writing.\n");
|
04878b | 2001-01-23 | John W. Pierce | | } else if (ret == 1) {
Pike_error("Duplicate key.\n");
}
|
178867 | 2007-04-25 | Henrik Grubbström (Grubba) | | ref_push_string(sp[1-args].u.string);
stack_pop_n_elems_keep_top(args);
}
static void gdbmmod_store_compat(INT32 args)
{
gdbmmod_store(args);
pop_stack();
push_int(1);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
fc293f | 2001-10-26 | Martin Nilsson | | |
584f6f | 2014-08-16 | Per Hedbor | | *! can take a LOT of time to run if the database is big.
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | static void gdbmmod_reorganize(INT32 args)
{
struct gdbm_glue *this=THIS;
int ret;
pop_n_elems(args);
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | THREADS_ALLOW();
mt_lock(& gdbm_lock);
ret=gdbm_reorganize(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
pop_n_elems(args);
push_int(ret);
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
584f6f | 2014-08-16 | Per Hedbor | | static void gdbmmod_sync(INT32 UNUSED(args))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
struct gdbm_glue *this=THIS;
|
b2d3e4 | 2000-12-01 | Fredrik Hübinette (Hubbe) | | if(!THIS->dbf) Pike_error("GDBM database not open.\n");
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | THREADS_ALLOW();
mt_lock(& gdbm_lock);
gdbm_sync(this->dbf);
mt_unlock(& gdbm_lock);
THREADS_DISALLOW();
}
|
584f6f | 2014-08-16 | Per Hedbor | |
static void gdbmmod_iter_first(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
gdbmmod_firstkey(0);
if( Pike_sp[-1].u.string )
this->iter = Pike_sp[-1].u.string;
Pike_sp--;
push_int( !!this->iter );
}
static void gdbmmod_iter_next(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
|
13670c | 2015-05-25 | Martin Nilsson | | if(!this->iter)
|
584f6f | 2014-08-16 | Per Hedbor | | {
push_undefined();
return;
}
push_string( this->iter );
gdbmmod_nextkey(1);
if( TYPEOF(Pike_sp[-1]) != PIKE_T_STRING )
{
this->iter = 0;
push_undefined();
return;
}
this->iter = Pike_sp[-1].u.string;
push_int(1);
return;
}
static void gdbmmod_iter_index(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
if( this->iter )
ref_push_string( this->iter );
else
push_undefined();
}
static void gdbmmod_iter_no_value(INT32 UNUSED(args))
{
push_int( !THIS->iter );
}
static void gdbmmod_iter_value(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
if( this->iter )
{
ref_push_string( this->iter );
|
13670c | 2015-05-25 | Martin Nilsson | | gdbmmod_fetch(1);
|
584f6f | 2014-08-16 | Per Hedbor | | }
else
push_undefined();
}
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! @note
*! Mainly useful when debugging, the returned list might not fit in
*! memory for large databases.
*/
static void gdbmmod_indices(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
struct svalue *start = Pike_sp;
gdbmmod_iter_first(0);
pop_stack();
while( this->iter )
{
ref_push_string( this->iter );
gdbmmod_iter_next(0);
pop_stack();
}
push_array(aggregate_array( Pike_sp-start ));
}
|
13670c | 2015-05-25 | Martin Nilsson | | *!
|
584f6f | 2014-08-16 | Per Hedbor | | *! @note
*! Mainly useful when debugging, the returned list might not fit in
*! memory for large databases.
*/
static void gdbmmod_values(INT32 UNUSED(args))
{
struct gdbm_glue *this=THIS;
struct svalue *start = Pike_sp;
gdbmmod_iter_first(0);
pop_stack();
while( this->iter )
{
ref_push_string( this->iter );
gdbmmod_fetch(1);
gdbmmod_iter_next(0);
pop_stack();
}
push_array(aggregate_array( Pike_sp-start ));
}
static void gdbmmod_get_iterator(INT32 UNUSED(args))
{
push_object( clone_object( iterator, 0 ) );
*((struct gdbm_glue *)Pike_sp[-1].u.object->storage) = *THIS;
apply(Pike_sp[-1].u.object, "first", 0);
pop_stack();
}
|
fc293f | 2001-10-26 | Martin Nilsson | | |
584f6f | 2014-08-16 | Per Hedbor | | *! Closes the database. The object is no longer usable after this function has been called.
*!
*! This is also done automatically when the object is destructed for
*! any reason (running out of references or explicit destruct, as an
*! example)
|
fc293f | 2001-10-26 | Martin Nilsson | | */
|
96f63c | 2015-11-25 | Henrik Grubbström (Grubba) | | static void gdbmmod_close(INT32 UNUSED(args))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
|
1458b9 | 1997-08-31 | Henrik Grubbström (Grubba) | | do_free();
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
c4be2f | 2013-11-03 | Arne Goedeke | | static void init_gdbm_glue(struct object *UNUSED(o))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
THIS->dbf=0;
|
584f6f | 2014-08-16 | Per Hedbor | | THIS->iter=0;
}
static void init_gdbm_iterator(struct object *UNUSED(o))
{
THIS->dbf=0;
THIS->iter=0;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | }
|
c4be2f | 2013-11-03 | Arne Goedeke | | static void exit_gdbm_glue(struct object *UNUSED(o))
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
do_free();
}
|
584f6f | 2014-08-16 | Per Hedbor | | static void exit_gdbm_iterator(struct object *UNUSED(o))
{
if( THIS->iter )
free_string( THIS->iter );
}
|
fc293f | 2001-10-26 | Martin Nilsson | |
|
584f6f | 2014-08-16 | Per Hedbor | |
|
fc293f | 2001-10-26 | Martin Nilsson | |
#endif /* defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM) */
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | | PIKE_MODULE_EXIT {
}
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
51ef5c | 2002-10-21 | Marcus Comstedt | | PIKE_MODULE_INIT
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | {
|
584f6f | 2014-08-16 | Per Hedbor | | struct program *db;
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #if defined(HAVE_GDBM_H) && defined(HAVE_LIBGDBM)
start_new_program();
|
90e978 | 1999-01-31 | Fredrik Hübinette (Hubbe) | | ADD_STORAGE(struct gdbm_glue);
|
13670c | 2015-05-25 | Martin Nilsson | |
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
04878b | 2001-01-23 | John W. Pierce | | ADD_FUNCTION("create", gdbmmod_create,
|
584f6f | 2014-08-16 | Per Hedbor | | tFunc(tOr(tVoid,tStr) tOr(tVoid,tStr), tVoid), ID_PROTECTED);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("close",gdbmmod_close,tFunc(tNone,tVoid),0);
|
04878b | 2001-01-23 | John W. Pierce | |
|
178867 | 2007-04-25 | Henrik Grubbström (Grubba) | | ADD_FUNCTION("store", gdbmmod_store_compat,
|
584f6f | 2014-08-16 | Per Hedbor | | tFunc(tStr8 tStr8 tOr(tInt01, tVoid), tInt), 0);
|
178867 | 2007-04-25 | Henrik Grubbström (Grubba) | |
|
04878b | 2001-01-23 | John W. Pierce | | ADD_FUNCTION("`[]=", gdbmmod_store,
|
584f6f | 2014-08-16 | Per Hedbor | | tFunc(tStr8 tSetvar(0, tStr8) tOr(tInt01, tVoid), tVar(0)), 0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | | ADD_FUNCTION("fetch",gdbmmod_fetch,tFunc(tStr,tStr8),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | | ADD_FUNCTION("`[]",gdbmmod_fetch,tFunc(tStr,tStr8),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
87a8f9 | 2003-05-25 | Martin Nilsson | | ADD_FUNCTION("delete",gdbmmod_delete,tFunc(tStr,tInt01),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | | ADD_FUNCTION("firstkey",gdbmmod_firstkey,tFunc(tNone,tStr8),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | | ADD_FUNCTION("nextkey",gdbmmod_nextkey,tFunc(tStr,tStr8),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("reorganize",gdbmmod_reorganize,tFunc(tNone,tInt),0);
|
45ee5d | 1999-02-10 | Fredrik Hübinette (Hubbe) | |
|
e64f5a | 1999-06-19 | Fredrik Hübinette (Hubbe) | | ADD_FUNCTION("sync",gdbmmod_sync,tFunc(tNone,tVoid),0);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | |
|
584f6f | 2014-08-16 | Per Hedbor | |
ADD_FUNCTION("_get_iterator", gdbmmod_get_iterator,tFunc(tNone,tObj),0);
ADD_FUNCTION("_m_delete",gdbmmod_m_delete,tFunc(tStr,tStr8),0);
ADD_FUNCTION("_values",gdbmmod_values,tFunc(tNone,tArr(tStr8)),0);
ADD_FUNCTION("_indices",gdbmmod_indices,tFunc(tNone,tArr(tStr8)),0);
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | set_init_callback(init_gdbm_glue);
set_exit_callback(exit_gdbm_glue);
|
584f6f | 2014-08-16 | Per Hedbor | | db = end_program();
|
bb4200 | 2014-10-27 | Henrik Grubbström (Grubba) | | add_program_constant( "DB", db, 0 );
add_program_constant( "gdbm", db, 0 );
free_program(db);
|
584f6f | 2014-08-16 | Per Hedbor | | start_new_program();
ADD_STORAGE(struct gdbm_glue);
ADD_FUNCTION("first", gdbmmod_iter_first,tFunc(tNone,tInt01),0);
ADD_FUNCTION("next", gdbmmod_iter_next, tFunc(tNone,tInt01),0);
ADD_FUNCTION("index", gdbmmod_iter_index,tFunc(tNone,tStr8),0);
ADD_FUNCTION("value", gdbmmod_iter_value,tFunc(tNone,tStr8),0);
ADD_FUNCTION("`!", gdbmmod_iter_no_value,tFunc(tNone,tInt01),0);
set_init_callback(init_gdbm_iterator);
set_exit_callback(exit_gdbm_iterator);
iterator = end_program();
add_program_constant( "Iterator", iterator, 0 );
|
bb4200 | 2014-10-27 | Henrik Grubbström (Grubba) | | free_program(iterator);
|
1fbe3e | 2005-11-14 | Martin Nilsson | | #else
|
ecb2c0 | 2014-10-05 | Martin Nilsson | | HIDE_MODULE();
|
a80a9c | 1997-02-11 | Fredrik Hübinette (Hubbe) | | #endif
}
|