DB_File.xs -- Perl 5 interface to Berkeley DB
- written by Paul Marquess (pmarquess@bfsec.bt.co.uk)
- last modified 16th May 1998
- version 1.60
+ written by Paul Marquess <Paul.Marquess@btinternet.com>
+ last modified 21st February 1999
+ version 1.64
All comments/suggestions/problems are welcome
- Copyright (c) 1995, 1996, 1997, 1998 Paul Marquess. All rights reserved.
+ Copyright (c) 1995-9 Paul Marquess. All rights reserved.
This program is free software; you can redistribute it and/or
modify it under the same terms as Perl itself.
This was ok for DB 1.x, but isn't for DB 2.x.
1.59 - No change to DB_File.xs
1.60 - Some code tidy up
+ 1.61 - added flagSet macro for DB 2.5.x
+ fixed typo in O_RDONLY test.
+ 1.62 - No change to DB_File.xs
+ 1.63 - Fix to alllow DB 2.6.x to build.
+ 1.64 - Tidied up the 1.x to 2.x flags mapping code.
+ Added a patch from Mark Kettenis <kettenis@wins.uva.nl>
+ to fix a flag mapping problem with O_RDONLY on the Hurd
#include "perl.h"
#include "XSUB.h"
+#ifndef PERL_VERSION
+#include "patchlevel.h"
+#define PERL_REVISION 5
+#define PERL_VERSION PATCHLEVEL
+#define PERL_SUBVERSION SUBVERSION
+#endif
+
+#if PERL_REVISION == 5 && (PERL_VERSION < 4 || (PERL_VERSION == 4 && PERL_SUBVERSION <= 75 ))
+
+# define PL_sv_undef sv_undef
+# define PL_na na
+
+#endif
+
/* Being the Berkeley DB we prefer the <sys/cdefs.h> (which will be
* shortly #included by the <db.h>) __attribute__ to the possibly
* already defined __attribute__, for example by GNUC or by Perl. */
#define DBT_flags(x) x.flags = 0
#define DB_flags(x, v) x |= v
+#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
+#define flagSet(flags, bitmask) ((flags) & (bitmask))
+#else
+#define flagSet(flags, bitmask) (((flags) & DB_OPFLAGS_MASK) == (bitmask))
+#endif
+
#else /* db version 1.x */
typedef union INFO {
#define do_SEQ(db, key, value, flag) (db->dbp->seq)(db->dbp, &key, &value, flag)
#define DBT_flags(x)
#define DB_flags(x, v)
+#define flagSet(flags, bitmask) ((flags) & (bitmask))
#endif /* db version 1 */
#define db_sync(db, flags) ((db->dbp)->sync)(db->dbp, flags)
#define db_get(db, key, value, flags) ((db->dbp)->get)(db->dbp, TXN &key, &value, flags)
+
#ifdef DB_VERSION_MAJOR
#define db_DESTROY(db) ((db->dbp)->close)(db->dbp, 0)
#define db_close(db) ((db->dbp)->close)(db->dbp, 0)
-#define db_del(db, key, flags) ((flags & R_CURSOR) \
+#define db_del(db, key, flags) (flagSet(flags, R_CURSOR) \
? ((db->cursor)->c_del)(db->cursor, 0) \
: ((db->dbp)->del)(db->dbp, NULL, &key, flags) )
#endif
+
#define db_seq(db, key, value, flags) do_SEQ(db, key, value, flags)
typedef struct {
{
int status ;
- if (flags & R_CURSOR) {
+ if (flagSet(flags, R_CURSOR)) {
status = ((db->cursor)->c_del)(db->cursor, 0);
if (status != 0)
return status ;
+#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 5
flags &= ~R_CURSOR ;
+#else
+ flags &= ~DB_OPFLAGS_MASK ;
+#endif
+
}
return ((db->dbp)->put)(db->dbp, NULL, &key, &value, flags) ;
croak("DB_File needs Berkeley DB 2.0.5 or greater, you have %d.%d.%d\n",
Major, Minor, Patch) ;
-#if PATCHLEVEL > 3
+#if PERL_VERSION > 3
sv_setpvf(ver_sv, "%d.%d", Major, Minor) ;
#else
{
DB_File RETVAL = (DB_File)safemalloc(sizeof(DB_File_type)) ;
void * openinfo = NULL ;
INFO * info = &RETVAL->info ;
+ STRLEN n_a;
/* printf("In ParseOpenInfo name=[%s] flags=[%d] mode = [%d]\n", name, flags, mode) ; */
Zero(RETVAL, 1, DB_File_type) ;
#endif
svp = hv_fetch(action, "bfname", 6, FALSE);
if (svp && SvOK(*svp)) {
- char * ptr = SvPV(*svp,na) ;
+ char * ptr = SvPV(*svp,n_a) ;
#ifdef DB_VERSION_MAJOR
- name = (char*) na ? ptr : NULL ;
+ name = (char*) n_a ? ptr : NULL ;
#else
- info->db_RE_bfname = (char*) (na ? ptr : NULL) ;
+ info->db_RE_bfname = (char*) (n_a ? ptr : NULL) ;
#endif
}
else
{
int value ;
if (SvPOK(*svp))
- value = (int)*SvPV(*svp, na) ;
+ value = (int)*SvPV(*svp, n_a) ;
else
value = SvIV(*svp) ;
if (svp && SvOK(*svp))
{
if (SvPOK(*svp))
- info->db_RE_bval = (u_char)*SvPV(*svp, na) ;
+ info->db_RE_bval = (u_char)*SvPV(*svp, n_a) ;
else
info->db_RE_bval = (u_char)(unsigned long) SvIV(*svp) ;
DB_flags(info->flags, DB_DELIMITER) ;
if ((flags & O_CREAT) == O_CREAT)
Flags |= DB_CREATE ;
-#ifdef O_NONBLOCK
- if ((flags & O_NONBLOCK) == O_NONBLOCK)
- Flags |= DB_EXCL ;
-#endif
-
#if O_RDONLY == 0
if (flags == O_RDONLY)
#else
- if (flags & O_RDONLY) == O_RDONLY)
+ if ((flags & O_RDONLY) == O_RDONLY && (flags & O_RDWR) != O_RDWR)
#endif
Flags |= DB_RDONLY ;
-#ifdef O_NONBLOCK
+#ifdef O_TRUNC
if ((flags & O_TRUNC) == O_TRUNC)
Flags |= DB_TRUNCATE ;
#endif
status = db_open(name, RETVAL->type, Flags, mode, NULL, openinfo, &RETVAL->dbp) ;
if (status == 0)
+#if DB_VERSION_MAJOR == 2 && DB_VERSION_MINOR < 6
status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor) ;
+#else
+ status = (RETVAL->dbp->cursor)(RETVAL->dbp, NULL, &RETVAL->cursor,
+ 0) ;
+#endif
if (status)
RETVAL->dbp = NULL ;
{
char * name = (char *) NULL ;
SV * sv = (SV *) NULL ;
+ STRLEN n_a;
if (items >= 3 && SvOK(ST(2)))
- name = (char*) SvPV(ST(2), na) ;
+ name = (char*) SvPV(ST(2), n_a) ;
if (items == 6)
sv = ST(5) ;
int i ;
int One ;
DB * Db = db->dbp ;
+ STRLEN n_a;
DBT_flags(key) ;
DBT_flags(value) ;
#endif
for (i = items-1 ; i > 0 ; --i)
{
- value.data = SvPV(ST(i), na) ;
- value.size = na ;
+ value.data = SvPV(ST(i), n_a) ;
+ value.size = n_a ;
One = 1 ;
key.data = &One ;
key.size = sizeof(int) ;
OutputValue(ST(0), value) ;
RETVAL = db_del(db, key, R_CURSOR) ;
if (RETVAL != 0)
- sv_setsv(ST(0), &sv_undef);
+ sv_setsv(ST(0), &PL_sv_undef);
}
}
OutputValue(ST(0), value) ;
RETVAL = db_del(db, key, R_CURSOR) ;
if (RETVAL != 0)
- sv_setsv (ST(0), &sv_undef) ;
+ sv_setsv (ST(0), &PL_sv_undef) ;
}
}
DBT value ;
DB * Db = db->dbp ;
int i ;
+ STRLEN n_a;
DBT_flags(key) ;
DBT_flags(value) ;
{
++ (* (int*)key.data) ;
- value.data = SvPV(ST(i), na) ;
- value.size = na ;
+ value.data = SvPV(ST(i), n_a) ;
+ value.size = n_a ;
RETVAL = (Db->put)(Db, NULL, &key, &value, 0) ;
if (RETVAL != 0)
break;
#else
for (i = items - 1 ; i > 0 ; --i)
{
- value.data = SvPV(ST(i), na) ;
- value.size = na ;
+ value.data = SvPV(ST(i), n_a) ;
+ value.size = n_a ;
RETVAL = (Db->put)(Db, keyptr, &value, R_IAFTER) ;
if (RETVAL != 0)
break;
#endif
OUTPUT:
RETVAL
- key if (flags & (R_IAFTER|R_IBEFORE)) OutputKey(ST(1), key);
+ key if (flagSet(flags, R_IAFTER) || flagSet(flags, R_IBEFORE)) OutputKey(ST(1), key);
int
db_fd(db)