|
From: <bc...@wo...> - 2001-04-13 17:11:33
|
[Andy Bulka]
> Love jython,
Me too.
> Cannot get shelves to work since (as the readme says) bsddb is not
>implemented. This is a pretty important piece of python that is missing -
>is there a reason for this?
bsddb require native code.
Sleepy cat (the maintainer of bsddb) have released a java binding for
their library. Using this binding (tested with version 2.7.3) you can
use the dbhash.py module below to get a bsddb module for jython. You
are on your own with getting bsddb compiled (both C and java) and
installed.
>Any chance of getting shelve working in the next release?
Shelve based on dumbdbm will work in the next release.
regards,
finn
#
# Copyright 1999 Finn Bock.
# Permission to use, copy and distribute this software is hereby granted,
# provided that the above copyright notice appear in all copies and that
# both that copyright notice and this permission notice appear.
#
# No Warranty
# The software is provided "as is" without warranty of any kind.
#
# If you have questions regarding this software, contact:
# Finn Bock, bc...@wo...
#
# This program contains material copyrighted by:
# Copyright 1991-1995 by Stichting Mathematisch Centrum, Amsterdam,
# The Netherlands.
#
# Note:
# The libdb.jar must be on your CLASSPATH.
# the libdb.dll and libdb_java.dll must be on your PATH.
#
# @version $Id: bsddb.py,v 1.8 1999/04/17 05:45:00 fb Exp $
#
import sys; sys.add_package("com.sleepycat.db")
from com.sleepycat import db
from java import lang
from jarray import array, zeros
error = "bsddb.error"
dbenv = db.DbEnv()
dbenv.set_error_stream(lang.System.err)
dbenv.set_errpfx("bsddb")
dbenv.set_mp_size(64*1024)
dbenv.appinit(".", None, 0)
class bsddbtype:
def __init__(self, bsddb):
self._db = bsddb
self._txn = None
self._seq = bsddb.cursor(self._txn, 0)
self._len = -1
def __len__(self):
if self._len < 0:
krec = db.Dbt()
krec.set_flags(db.Db.DB_DBT_MALLOC)
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
cnt = 0
status = self._seq.get(krec, drec, db.Db.DB_FIRST)
while status == 0:
cnt = cnt + 1
status = self._seq.get(krec, drec, db.Db.DB_NEXT)
self._len = cnt
return self._len
def __getitem__(self, key):
krec = db.Dbt(key)
krec.set_size(len(key))
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
status = self._db.get(self._txn, krec, drec, 0)
if status:
if status == db.Db.DB_NOTFOUND:
raise KeyError, key
else:
raise error, status
return drec.get_data().tostring()
def __setitem__(self, key, value):
krec = db.Dbt(key)
krec.set_size(len(key))
drec = db.Dbt(value)
drec.set_size(len(value))
status = self._db.put(self._txn, krec, drec, 0)
if status:
if status == db.Db.DB_NOTFOUND:
raise KeyError, key
else:
raise error, status
self._len = -1
def __delitem__(self, key):
#print "__delitem__", key, len(key), type(key)
krec = db.Dbt(key)
krec.set_size(len(key))
try:
self._db.del_(self._txn, krec, 0)
except db.DbException, e:
if e.get_errno() == db.Db.DB_NOTFOUND:
raise KeyError, key
else:
raise error, e.message
self._len = -1
def close(self):
self._seq.close()
self._db.close(0)
self._seq = None
self._db = None
def keys(self):
krec = db.Dbt()
krec.set_flags(db.Db.DB_DBT_MALLOC)
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
list = []
status = self._seq.get(krec, drec, db.Db.DB_FIRST)
while status == 0:
list.append(krec.get_data().tostring())
status = self._seq.get(krec, drec, db.Db.DB_NEXT)
self._len = len(list)
return list
def has_key(self, key):
krec = db.Dbt(key)
krec.set_size(len(key))
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
status = self._db.get(self._txn, krec, drec, 0)
return status == 0
def set_location(self, key):
krec = db.Dbt(key)
krec.set_size(len(key))
krec.set_flags(db.Db.DB_DBT_MALLOC)
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
status = self._seq.get(krec, drec, db.Db.DB_SET_RANGE)
if status != 0:
if status == db.Db.DB_NOTFOUND:
raise KeyError, key
else:
raise error, status
return (krec.get_data()[:krec.get_size()].tostring(), drec.get_data().tostring())
def _dbseq(self, seq_request):
#print "_dbseq", seq_request
krec = db.Dbt()
krec.set_flags(db.Db.DB_DBT_MALLOC)
drec = db.Dbt()
drec.set_flags(db.Db.DB_DBT_MALLOC)
status = self._seq.get(krec, drec, seq_request)
if status != 0:
raise KeyError
return (krec.get_data().tostring(), drec.get_data().tostring())
def next(self):
return self._dbseq(db.Db.DB_NEXT)
def previous(self):
return self._dbseq(db.Db.DB_PREV)
def first(self):
return self._dbseq(db.Db.DB_FIRST)
def last(self):
return self._dbseq(db.Db.DB_LAST)
def sync(self):
self._db.sync(0)
def __flags(flag):
flags=db.Db.DB_RDONLY
if flag:
if flag[0] == 'r':
flags = db.Db.DB_RDONLY
elif flag[0] == 'w':
flags = 0
elif flag[0] == 'c':
flags = db.Db.DB_CREATE
elif flag[0] == 'n':
flags = db.Db.DB_CREATE | db.Db.DB_TRUNCATE
else:
raise BsddbError, "Flag should begin with 'r', 'w', 'c' or 'n'"
if len(flag) > 1 and flag[1] == 'l':
if flag[0] == 'r':
flags = flags | db.Db.DB_SHLOCK
else:
flags = flags | db.Db.DB_EXLOCK
return flags
def btopen(file, flag=None, mode=0666, btflags=0,
cachesize=0, maxkeypage=0, minkeypage=0, psize=0, lorder=0):
flags=__flags(flag)
info = db.DbInfo()
info.set_flags(btflags)
info.set_pagesize(psize)
info.set_lorder(lorder)
info.set_cachesize(cachesize)
#info.set_bt_minkey(minkeypage)
# maxkeypage,bsize ignored
return bsddbtype(db.Db.open(file, db.Db.DB_BTREE, flags, mode, dbenv, info))
def hashopen(file, flag=None, mode=0666, bsize=0,
ffactor=0, nelem=0, cachesize=0, hash=0, lorder=0):
flags=__flags(flag)
info = db.DbInfo()
info.set_cachesize(cachesize)
info.set_lorder(lorder)
info.set_h_ffactor(ffactor)
info.set_h_nelem(nelem)
# hash & bsize ignored
return bsddbtype(db.Db.open(file, db.Db.DB_HASH, flags, mode, dbenv, info))
def rnopen(file, flag=None, mode=0666, rnflags=0,
cachesize=0, psize=0, lorder=0, reclen=0, bval="", bfname=None):
flags=__flags(flag)
info = db.DbInfo()
info.set_flags(rnflags)
info.set_cachesize(cachesize)
info.set_pagesize(psize)
info.set_lorder(lorder)
info.set_re_len(reclen)
if len(bval):
info.set_re_pad(bval[0])
if bfname:
info.set_re_source(bfname)
# hash & bsize ignored
return bsddbtype(db.Db.open(file, db.Db.DB_RECNO, flags, mode, dbenv, info))
if __name__ == "__main__":
tstdb = btopen("test.db", "n", 0666)
tstdb["100"] = "data100"
tstdb["101"] = "data100"
tstdb["099"] = "data100"
iterator = tstdb._db.cursor(None)
key = db.Dbt()
key.set_flags(db.Db.DB_DBT_MALLOC)
data = db.Dbt()
data.set_flags(db.Db.DB_DBT_MALLOC)
while iterator.get(key, data, db.Db.DB_NEXT) == 0:
ks = lang.String(key.get_data(), 0, key.get_size())
kd = lang.String(data.get_data(), 0, data.get_size())
print ks, ":", kd
iterator.close();
print tstdb["100"]
print tstdb["099"]
|