/***********************************************************
Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
The Netherlands.

                        All Rights Reserved

Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the names of Stichting Mathematisch
Centrum or CWI or Corporation for National Research Initiatives or
CNRI not be used in advertising or publicity pertaining to
distribution of the software without specific, written prior
permission.

While CWI is the initial source for this software, a modified version
is made available by the Corporation for National Research Initiatives
(CNRI) at the Internet address ftp://ftp.python.org.

STICHTING MATHEMATISCH CENTRUM AND CNRI DISCLAIM ALL WARRANTIES WITH
REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF
MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL STICHTING MATHEMATISCH
CENTRUM OR CNRI BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL
DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
PERFORMANCE OF THIS SOFTWARE.

******************************************************************/

/* DBM module using dictionary interface */
/* Author: Anthony Baxter, after dbmmodule.c */
/* Doc strings: Mitch Chapman */


#include "Python.h"

#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "gdbm.h"

static char gdbmmodule__doc__[] = "\
This module provides an interface to the GNU DBM (GDBM) library.\n\
\n\
This module is quite similar to the dbm module, but uses GDBM instead to\n\
provide some additional functionality. Please note that the file formats\n\
created by GDBM and dbm are incompatible. \n\
\n\
GDBM objects behave like mappings (dictionaries), except that keys and\n\
values are always strings. Printing a GDBM object doesn't print the\n\
keys and values, and the items() and values() methods are not\n\
supported.";

typedef struct {
	PyObject_HEAD
	int di_size;	/* -1 means recompute */
	GDBM_FILE di_dbm;
} dbmobject;

staticforward PyTypeObject Dbmtype;

#define is_dbmobject(v) ((v)->ob_type == &Dbmtype)
#define check_dbmobject_open(v) if ((v)->di_dbm == NULL) \
               { PyErr_SetString(DbmError, "GDBM object has already been closed"); \
                 return NULL; }



static PyObject *DbmError;

static char gdbm_object__doc__[] = "\
This object represents a GDBM database.\n\
GDBM objects behave like mappings (dictionaries), except that keys and\n\
values are always strings. Printing a GDBM object doesn't print the\n\
keys and values, and the items() and values() methods are not\n\
supported.\n\
\n\
GDBM objects also support additional operations such as firstkey,\n\
nextkey, reorganize, and sync.";

static PyObject *
newdbmobject(file, flags, mode)
	char *file;
int flags;
int mode;
{
        dbmobject *dp;

	dp = PyObject_NEW(dbmobject, &Dbmtype);
	if (dp == NULL)
		return NULL;
	dp->di_size = -1;
	errno = 0;
	if ( (dp->di_dbm = gdbm_open(file, 0, flags, mode, NULL)) == 0 ) {
		if (errno != 0)
			PyErr_SetFromErrno(DbmError);
		else
			PyErr_SetString(DbmError,
					(char *) gdbm_strerror(gdbm_errno));
		Py_DECREF(dp);
		return NULL;
	}
	return (PyObject *)dp;
}

/* Methods */

static void
dbm_dealloc(dp)
	register dbmobject *dp;
{
        if ( dp->di_dbm )
		gdbm_close(dp->di_dbm);
	PyMem_DEL(dp);
}

static int
dbm_length(dp)
	dbmobject *dp;
{
        if (dp->di_dbm == NULL) {
                 PyErr_SetString(DbmError, "GDBM object has already been closed"); 
                 return -1; 
        }
        if ( dp->di_size < 0 ) {
		datum key,okey;
		int size;
		okey.dsize=0;

		size = 0;
		for ( key=gdbm_firstkey(dp->di_dbm); key.dptr;
		      key = gdbm_nextkey(dp->di_dbm,okey)) {
			size++;
			if(okey.dsize) free(okey.dptr);
			okey=key;
		}
		dp->di_size = size;
	}
	return dp->di_size;
}

static PyObject *
dbm_subscript(dp, key)
	dbmobject *dp;
register PyObject *key;
{
	PyObject *v;
	datum drec, krec;
	
	if (!PyArg_Parse(key, "s#", &krec.dptr, &krec.dsize) )
		return NULL;
	
	drec = gdbm_fetch(dp->di_dbm, krec);
	if ( drec.dptr == 0 ) {
		PyErr_SetString(PyExc_KeyError,
				PyString_AS_STRING((PyStringObject *)key));
		return NULL;
	}
	v = PyString_FromStringAndSize(drec.dptr, drec.dsize);
	free(drec.dptr);
	return v;
}

static int
dbm_ass_sub(dp, v, w)
	dbmobject *dp;
PyObject *v, *w;
{
        datum krec, drec;
	
        if ( !PyArg_Parse(v, "s#", &krec.dptr, &krec.dsize) ) {
		PyErr_SetString(PyExc_TypeError,
				"gdbm mappings have string indices only");
		return -1;
	}
        if (dp->di_dbm == NULL) {
                 PyErr_SetString(DbmError, "GDBM object has already been closed"); 
                 return -1; 
        }
	dp->di_size = -1;
	if (w == NULL) {
		if ( gdbm_delete(dp->di_dbm, krec) < 0 ) {
			PyErr_SetString(PyExc_KeyError,
				      PyString_AS_STRING((PyStringObject *)v));
			return -1;
		}
	} else {
		if ( !PyArg_Parse(w, "s#", &drec.dptr, &drec.dsize) ) {
			PyErr_SetString(PyExc_TypeError,
				    "gdbm mappings have string elements only");
			return -1;
		}
		errno = 0;
		if ( gdbm_store(dp->di_dbm, krec, drec, GDBM_REPLACE) < 0 ) {
			if (errno != 0)
				PyErr_SetFromErrno(DbmError);
			else
				PyErr_SetString(DbmError,
					   (char *) gdbm_strerror(gdbm_errno));
			return -1;
		}
	}
	return 0;
}

static PyMappingMethods dbm_as_mapping = {
	(inquiry)dbm_length,		/*mp_length*/
	(binaryfunc)dbm_subscript,	/*mp_subscript*/
	(objobjargproc)dbm_ass_sub,	/*mp_ass_subscript*/
};

static char dbm_close__doc__[] = "\
close() -> None\n\
Closes the database.";

static PyObject *
dbm_close(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	if ( !PyArg_NoArgs(args) )
		return NULL;
        if ( dp->di_dbm )
		gdbm_close(dp->di_dbm);
	dp->di_dbm = NULL;
	Py_INCREF(Py_None);
	return Py_None;
}

static char dbm_keys__doc__[] = "\
keys() -> list_of_keys\n\
Get a list of all keys in the database.";

static PyObject *
dbm_keys(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	register PyObject *v, *item;
	datum key, nextkey;
	int err;

	if (dp == NULL || !is_dbmobject(dp)) {
		PyErr_BadInternalCall();
		return NULL;
	}

	if (!PyArg_NoArgs(args))
		return NULL;

	check_dbmobject_open(dp);

	v = PyList_New(0);
	if (v == NULL)
		return NULL;

	key = gdbm_firstkey(dp->di_dbm);
	while (key.dptr) {
		item = PyString_FromStringAndSize(key.dptr, key.dsize);
		if (item == NULL) {
			free(key.dptr);
			Py_DECREF(v);
			return NULL;
		}
		err = PyList_Append(v, item);
		Py_DECREF(item);
		if (err != 0) {
			free(key.dptr);
			Py_DECREF(v);
			return NULL;
		}
		nextkey = gdbm_nextkey(dp->di_dbm, key);
		free(key.dptr);
		key = nextkey;
	}

	return v;
}

static char dbm_has_key__doc__[] = "\
has_key(key) -> boolean\n\
Find out whether or not the database contains a given key.";

static PyObject *
dbm_has_key(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	datum key;
	
	if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
		return NULL;
	check_dbmobject_open(dp);
	return PyInt_FromLong((long) gdbm_exists(dp->di_dbm, key));
}

static char dbm_firstkey__doc__[] = "\
firstkey() -> key\n\
It's possible to loop over every key in the database using this method\n\
and the nextkey() method. The traversal is ordered by GDBM's internal\n\
hash values, and won't be sorted by the key values. This method\n\
returns the starting key.";

static PyObject *
dbm_firstkey(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	register PyObject *v;
	datum key;

	if (!PyArg_NoArgs(args))
		return NULL;
	check_dbmobject_open(dp);
	key = gdbm_firstkey(dp->di_dbm);
	if (key.dptr) {
		v = PyString_FromStringAndSize(key.dptr, key.dsize);
		free(key.dptr);
		return v;
	} else {
		Py_INCREF(Py_None);
		return Py_None;
	}
}

static char dbm_nextkey__doc__[] = "\
nextkey(key) -> next_key\n\
Returns the key that follows key in the traversal.\n\
The following code prints every key in the database db, without having\n\
to create a list in memory that contains them all:\n\
\n\
      k = db.firstkey()\n\
      while k != None:\n\
          print k\n\
          k = db.nextkey(k)";

static PyObject *
dbm_nextkey(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	register PyObject *v;
	datum key, nextkey;

	if (!PyArg_Parse(args, "s#", &key.dptr, &key.dsize))
		return NULL;
	check_dbmobject_open(dp);
	nextkey = gdbm_nextkey(dp->di_dbm, key);
	if (nextkey.dptr) {
		v = PyString_FromStringAndSize(nextkey.dptr, nextkey.dsize);
		free(nextkey.dptr);
		return v;
	} else {
		Py_INCREF(Py_None);
		return Py_None;
	}
}

static char dbm_reorganize__doc__[] = "\
reorganize() -> None\n\
If you have carried out a lot of deletions and would like to shrink\n\
the space used by the GDBM file, this routine will reorganize the\n\
database. GDBM will not shorten the length of a database file except\n\
by using this reorganization; otherwise, deleted file space will be\n\
kept and reused as new (key,value) pairs are added.";

static PyObject *
dbm_reorganize(dp, args)
	register dbmobject *dp;
PyObject *args;
{
	if (!PyArg_NoArgs(args))
		return NULL;
	check_dbmobject_open(dp);
	errno = 0;
	if (gdbm_reorganize(dp->di_dbm) < 0) {
		if (errno != 0)
			PyErr_SetFromErrno(DbmError);
		else
			PyErr_SetString(DbmError,
					(char *) gdbm_strerror(gdbm_errno));
		return NULL;
	}
	Py_INCREF(Py_None);
	return Py_None;
}

static char dbm_sync__doc__[] = "\
sync() -> None\n\
When the database has been opened in fast mode, this method forces\n\
any unwritten data to be written to the disk.";

static PyObject *
dbm_sync(dp, args)
	register dbmobject *dp;
                PyObject *args;
{
	if (!PyArg_NoArgs(args))
		return NULL;
	check_dbmobject_open(dp);
	gdbm_sync(dp->di_dbm);
	Py_INCREF(Py_None);
	return Py_None;
}

static PyMethodDef dbm_methods[] = {
	{"close",	(PyCFunction)dbm_close, 0, dbm_close__doc__},
	{"keys",	(PyCFunction)dbm_keys, 0, dbm_keys__doc__},
	{"has_key",	(PyCFunction)dbm_has_key, 0, dbm_has_key__doc__},
	{"firstkey",	(PyCFunction)dbm_firstkey, 0, dbm_firstkey__doc__},
	{"nextkey",	(PyCFunction)dbm_nextkey, 0, dbm_nextkey__doc__},
	{"reorganize",	(PyCFunction)dbm_reorganize, 0, dbm_reorganize__doc__},
	{"sync",                    (PyCFunction)dbm_sync, 0, dbm_sync__doc__},
	{NULL,		NULL}		/* sentinel */
};

static PyObject *
dbm_getattr(dp, name)
	dbmobject *dp;
char *name;
{
	return Py_FindMethod(dbm_methods, (PyObject *)dp, name);
}

static PyTypeObject Dbmtype = {
	PyObject_HEAD_INIT(&PyType_Type)
	0,
	"gdbm",
	sizeof(dbmobject),
	0,
	(destructor)dbm_dealloc,   /*tp_dealloc*/
	0,			   /*tp_print*/
	(getattrfunc)dbm_getattr,  /*tp_getattr*/
	0,			   /*tp_setattr*/
	0,			   /*tp_compare*/
	0,			   /*tp_repr*/
	0,			   /*tp_as_number*/
	0,			   /*tp_as_sequence*/
	&dbm_as_mapping,	   /*tp_as_mapping*/
        0,                         /*tp_hash*/
        0,                         /*tp_call*/
        0,                         /*tp_str*/
        0,                         /*tp_getattro*/
        0,                         /*tp_setattro*/
        0,                         /*tp_as_buffer*/
        0,                         /*tp_xxx4*/
        gdbm_object__doc__,        /*tp_doc*/
};

/* ----------------------------------------------------------------- */

static char dbmopen__doc__[] = "\
open(filename, [flag, [mode]])  -> dbm_object\n\
Open a dbm database and return a dbm object. The filename argument is\n\
the name of the database file.\n\
\n\
The optional flag argument can be 'r' (to open an existing database\n\
for reading only -- default), 'w' (to open an existing database for\n\
reading and writing), 'c' (which creates the database if it doesn't\n\
exist), or 'n' (which always creates a new empty database).\n\
\n\
Appending f to the flag opens the database in fast mode; altered\n\
data will not automatically be written to the disk after every\n\
change. This results in faster writes to the database, but may\n\
result in an inconsistent database if the program crashes while the\n\
database is still open. Use the sync() method to force any\n\
unwritten data to be written to the disk.\n\
\n\
The optional mode argument is the Unix mode of the file, used only\n\
when the database has to be created. It defaults to octal 0666. ";

static PyObject *
dbmopen(self, args)
	PyObject *self;
PyObject *args;
{
	char *name;
	char *flags = "r ";
	int iflags;
	int mode = 0666;

	if ( !PyArg_ParseTuple(args, "s|si", &name, &flags, &mode) )
		return NULL;
	switch (flags[0]) {
	case 'r':
		iflags = GDBM_READER;
		break;
	case 'w':
		iflags = GDBM_WRITER;
		break;
	case 'c':
		iflags = GDBM_WRCREAT;
		break;
	case 'n':
		iflags = GDBM_NEWDB;
		break;
	default:
		PyErr_SetString(DbmError,
				"Flags should be one of 'r', 'w', 'c' or 'n'");
		return NULL;
	}
	if (flags[1] == 'f')
		iflags |= GDBM_FAST;
	return newdbmobject(name, iflags, mode);
}

static PyMethodDef dbmmodule_methods[] = {
	{ "open", (PyCFunction)dbmopen, 1, dbmopen__doc__},
	{ 0, 0 },
};

void
initgdbm() {
	PyObject *m, *d;

	m = Py_InitModule4("gdbm", dbmmodule_methods,
                           gdbmmodule__doc__, (PyObject *)NULL,
			   PYTHON_API_VERSION);
	d = PyModule_GetDict(m);
	DbmError = PyErr_NewException("gdbm.error", NULL, NULL);
	if (DbmError != NULL)
		PyDict_SetItemString(d, "error", DbmError);
}
