Ensure that environment maintanence runs regularly.
[didex.git] / didex / index.py
index 65b1b12..0608318 100644 (file)
@@ -2,7 +2,7 @@ import struct, contextlib, math
 from . import db, lib
 from .db import bd, txnfun, dloopfun
 
-__all__ = ["maybe", "t_int", "t_uint", "t_dbid", "t_float", "t_str", "ordered"]
+__all__ = ["maybe", "t_bool", "t_int", "t_uint", "t_dbid", "t_float", "t_str", "t_casestr", "ordered"]
 
 deadlock = bd.DBLockDeadlockError
 notfound = bd.DBNotFoundError
@@ -29,6 +29,14 @@ class simpletype(object):
         return cls(lambda ob: struct.pack(fmt, ob),
                    lambda dat: struct.unpack(fmt, dat)[0])
 
+class foldtype(simpletype):
+    def __init__(self, encode, decode, fold):
+        super().__init__(encode, decode)
+        self.fold = fold
+
+    def compare(self, a, b):
+        return super().compare(self.fold(a), self.fold(b))
+
 class maybe(object):
     def __init__(self, bk):
         self.bk = bk
@@ -132,12 +140,15 @@ def floatcmp(a, b):
     else:
         return 0
 
+t_bool = simpletype((lambda ob: b"\x01" if ob else b"\x00"), (lambda dat: False if dat == b"x\00" else True))
 t_int = simpletype.struct(">q")
 t_uint = simpletype.struct(">Q")
 t_dbid = t_uint
 t_float = simpletype.struct(">d")
 t_float.compare = floatcmp
 t_str = simpletype((lambda ob: ob.encode("utf-8")), (lambda dat: dat.decode("utf-8")))
+t_casestr = foldtype((lambda ob: ob.encode("utf-8")), (lambda dat: dat.decode("utf-8")),
+                     (lambda st: st.lower()))
 
 class index(object):
     def __init__(self, db, name, datatype):
@@ -148,9 +159,9 @@ class index(object):
 missing = object()
 
 class ordered(index, lib.closable):
-    def __init__(self, db, name, datatype, create=True):
+    def __init__(self, db, name, datatype, create=True, *, tx=None):
         super().__init__(db, name, datatype)
-        fl = bd.DB_THREAD | bd.DB_AUTO_COMMIT
+        fl = bd.DB_THREAD
         if create: fl |= bd.DB_CREATE
         def initdb(db):
             def compare(a, b):
@@ -158,7 +169,7 @@ class ordered(index, lib.closable):
                 return self.typ.compare(self.typ.decode(a), self.typ.decode(b))
             db.set_flags(bd.DB_DUPSORT)
             db.set_bt_compare(compare)
-        self.bk = db._opendb("i-" + name, bd.DB_BTREE, fl, initdb)
+        self.bk = db._opendb("i-" + name, bd.DB_BTREE, fl, initdb, tx=tx)
         self.bk.set_get_returns_none(False)
 
     def close(self):
@@ -299,7 +310,7 @@ class ordered(index, lib.closable):
             if not done:
                 cur.close()
 
-    @txnfun(lambda self: self.db.env.env)
+    @txnfun(lambda self: self.db.env)
     def put(self, key, id, *, tx):
         obid = struct.pack(">Q", id)
         if not self.db.ob.has_key(obid, txn=tx.tx):
@@ -310,7 +321,7 @@ class ordered(index, lib.closable):
             return False
         return True
 
-    @txnfun(lambda self: self.db.env.env)
+    @txnfun(lambda self: self.db.env)
     def remove(self, key, id, *, tx):
         obid = struct.pack(">Q", id)
         if not self.db.ob.has_key(obid, txn=tx.tx):