[elephant-cvs] CVS elephant/src/db-bdb

ieslick ieslick at common-lisp.net
Fri Feb 2 23:51:58 UTC 2007


Update of /project/elephant/cvsroot/elephant/src/db-bdb
In directory clnet:/tmp/cvs-serv3271/src/db-bdb

Modified Files:
	bdb-collections.lisp bdb-controller.lisp bdb-slots.lisp 
	bdb-transactions.lisp berkeley-db.lisp 
Log Message:
Large changeset to enable thread safety; more *auto-commit* removal; sql class-root fix; new transaction model; cleaned up defaults for *store-controller*

--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-collections.lisp	2007/02/01 15:19:49	1.13
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-collections.lisp	2007/02/02 23:51:58	1.14
@@ -110,14 +110,14 @@
 (defmethod build-btree-index ((sc bdb-store-controller) &key primary key-form)
   (make-instance 'bdb-btree-index :primary primary :key-form key-form :sc sc))
 
-(defmethod add-index ((bt bdb-indexed-btree) &key index-name key-form populate)
+(defmethod add-index ((bt bdb-indexed-btree) &key index-name key-form (populate t))
   (let ((sc (get-con bt)))
 ;; Setting the value of *store-controller* is unfortunately
 ;; absolutely required at present, I think because the copying 
 ;; of objects is calling "make-instance" without an argument.
 ;; I am sure I can find a way to make this cleaner, somehow.
     (if (and (not (null index-name))
-	     (symbolp index-name) 
+	     (symbolp index-name)
 	     (or (symbolp key-form) (listp key-form)))
 	;; Can it be that this fails?
 	(let ((ht (indices bt))
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-controller.lisp	2007/02/01 04:03:26	1.19
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-controller.lisp	2007/02/02 23:51:58	1.20
@@ -62,7 +62,7 @@
 ;;
 
 (defmethod open-controller ((sc bdb-store-controller) &key (recover nil)
-			    (recover-fatal nil) (thread t) (errfile nil)
+			    (recover-fatal nil) (thread t) ;; (errfile nil)
 			    (deadlock-detect nil))
   (let ((env (db-env-create)))
     (setf (controller-environment sc) env)
@@ -158,7 +158,7 @@
   "Get the next OID."
   (declare (type bdb-store-controller sc))
   (db-sequence-get-fixnum (controller-oid-seq sc) 1 :transaction +NULL-VOID+
-			  :auto-commit t :txn-nosync t))
+			  :txn-nosync t))
 
 ;;
 ;; Automated Deadlock Support
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-slots.lisp	2007/01/22 22:22:35	1.1
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-slots.lisp	2007/02/02 23:51:58	1.2
@@ -23,8 +23,9 @@
 ;; Persistent slot protocol implementation
 ;;
 
+(declaim #-elephant-without-optimize (optimize (speed 3) (safety 1) (space 0)))
+
 (defmethod persistent-slot-reader ((sc bdb-store-controller) instance name)
-;;  (declare (optimize (speed 3) (safety 1) (space 1)))
   (with-buffer-streams (key-buf value-buf)
     (buffer-write-int (oid instance) key-buf)
     (serialize name key-buf sc)
@@ -37,20 +38,16 @@
 	  (error 'unbound-slot :instance instance :name name)))))
 
 (defmethod persistent-slot-writer ((sc bdb-store-controller) new-value instance name)
-;;  (declare (optimize (speed 3) (safety 1) (space 1)))
-;;  (format t "psw -- sc: ~A  ct: ~A ac: ~A~%" *store-controller* *current-transaction* *auto-commit*)
   (with-buffer-streams (key-buf value-buf)
     (buffer-write-int (oid instance) key-buf)
     (serialize name key-buf sc)
     (serialize new-value value-buf sc)
     (db-put-buffered (controller-db sc)
 		     key-buf value-buf
-		     :transaction *current-transaction*
-		     :auto-commit *auto-commit*)
+		     :transaction (txn-default *current-transaction*))
     new-value))
 
 (defmethod persistent-slot-boundp ((sc bdb-store-controller) instance name)
-;;  (declare (optimize (speed 3) (safety 1) (space 1)))
   (with-buffer-streams (key-buf value-buf)
     (buffer-write-int (oid instance) key-buf)
     (serialize name key-buf sc)
@@ -59,10 +56,8 @@
       (if buf t nil))))
 
 (defmethod persistent-slot-makunbound ((sc bdb-store-controller) instance name)
-;;  (declare (optimize (speed 3) (safety 1) (space 1)))
   (with-buffer-streams (key-buf)
     (buffer-write-int (oid instance) key-buf)
     (serialize name key-buf sc)
     (db-delete-buffered (controller-db sc) key-buf
-			:transaction *current-transaction*
-			:auto-commit *auto-commit*)))
+			:transaction (txn-default *current-transaction*))))
--- /project/elephant/cvsroot/elephant/src/db-bdb/bdb-transactions.lisp	2006/11/11 18:41:10	1.4
+++ /project/elephant/cvsroot/elephant/src/db-bdb/bdb-transactions.lisp	2007/02/02 23:51:58	1.5
@@ -21,11 +21,10 @@
 
 (defmethod execute-transaction ((sc bdb-store-controller) txn-fn
 				&key 
-				transaction environment parent
-				(retries 100) degree-2
-				dirty-read txn-nosync txn-nowait txn-sync)
-  (let ((env (if environment environment 
-		 (controller-environment sc))))
+				transaction parent environment
+				(retries 100) 
+				degree-2 dirty-read txn-nosync txn-nowait txn-sync)
+  (let ((env (if environment environment (controller-environment sc))))
     (loop 
        for count fixnum from 1 to retries
        for success of-type boolean = nil
@@ -33,7 +32,7 @@
        (let ((txn
 	      (if transaction transaction
 		  (db-transaction-begin env
-					:parent parent
+					:parent (if parent parent +NULL-VOID+)
 					:degree-2 degree-2
 					:dirty-read dirty-read
 					:txn-nosync txn-nosync
@@ -42,20 +41,17 @@
 	 (declare (type pointer-void txn)
 		  (dynamic-extent txn))
 	 (let ((result
-		(let ((*current-transaction* txn)
-		      (*auto-commit* nil))
-		  (declare (special *current-transaction* *auto-commit*))
-;;			   (dynamic-extent *current-transaction* *auto-commit*))
+		(let ((*current-transaction* txn))
+		  (declare (special *current-transaction*))
 		  (catch 'transaction
 		    (unwind-protect
 			 (prog1 
 			     (funcall txn-fn)
 			   (setq success t)
-			   (db-transaction-commit :transaction txn 
-						  :txn-nosync txn-nosync
-						  :txn-sync txn-sync))
+			   (db-transaction-commit txn :txn-nosync txn-nosync
+						      :txn-sync txn-sync))
 		      (unless success 
-			(db-transaction-abort :transaction txn)))))))
+			(db-transaction-abort txn)))))))
 	   (unless (and (eq result txn) (not success))
 	     (return result))))
        finally (error "Too many retries in transaction"))))
@@ -79,6 +75,7 @@
 					 dirty-read
 					 degree-2
 					 &allow-other-keys)
+  (assert (not *current-transaction*))
   (db-transaction-begin (controller-environment sc)
 			:parent parent
 			:txn-nosync txn-nosync
@@ -88,8 +85,101 @@
 			:degree-2 degree-2))
 			
 
-(defmethod controller-commit-transaction ((sc bdb-store-controller) &key transaction &allow-other-keys)
-  (db-transaction-commit :transaction transaction))
+(defmethod controller-commit-transaction ((sc bdb-store-controller) transaction &key &allow-other-keys)
+  (assert (not *current-transaction*))
+  (db-transaction-commit transaction))
 
-(defmethod controller-abort-transaction ((sc bdb-store-controller) &key &allow-other-keys)
-  (db-transaction-abort))
\ No newline at end of file
+(defmethod controller-abort-transaction ((sc bdb-store-controller) transaction &key &allow-other-keys)
+  (assert (not *current-transaction*))
+  (db-transaction-abort transaction))
+
+
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+;; Old versions of with-transaction
+;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
+
+#|
+(defmacro with-transaction ((&key transaction environment
+				  (parent '*current-transaction*)
+				  (retries 100)
+				  dirty-read read-uncommitted 
+				  txn-nosync txn-nowait txn-sync)
+			    &body body)
+  (let ((txn (if transaction transaction (gensym)))
+	(count (gensym))
+	(result (gensym))
+	(success (gensym)))
+    `(loop 
+      for ,count fixnum from 1 to ,retries
+      for ,success of-type boolean = nil
+      do
+      (with-alien ((,txn (* t)
+			 (db-transaction-begin ,environment
+					       :parent ,parent
+					       :dirty-read (or ,dirty-read ,read-uncommitted)
+					       :txn-nosync ,txn-nosync
+					       :txn-nowait ,txn-nowait
+					       :txn-sync ,txn-sync)))
+	(let ((,result
+	       (let ((*current-transaction* ,txn))
+		 (declare (special *current-transaction*)
+			  (dynamic-extent *current-transaction*))
+		 (catch 'transaction
+		   (unwind-protect
+			(prog1 (progn , at body)
+			  (setq ,success t)
+			  (db-transaction-commit :transaction ,txn 
+						 :txn-nosync ,txn-nosync
+						 :txn-sync ,txn-sync))
+		     (unless ,success 
+		       (db-transaction-abort :transaction ,txn)))))))
+	  (unless (and (eq ,result ,txn) (not ,success))
+	    (return ,result))))
+      finally (error "Too many retries")))) 
+
+(defmacro with-transaction ((&key transaction environment
+				  (parent '*current-transaction*)
+				  (retries 100)
+				  degree-2 read-committed 
+				  dirty-read read-uncommitted 
+				  txn-nosync txn-nowait txn-sync)
+			    &body body)
+  "Execute a body with a transaction in place.  On success,
+the transaction is committed.  Otherwise, the transaction is
+aborted.  If the body deadlocks, the body is re-executed in
+a new transaction, retrying a fixed number of iterations."
+  (let ((txn (if transaction transaction (gensym)))
+	(count (gensym))
+	(result (gensym))
+	(success (gensym)))
+    `(loop 
+      for ,count fixnum from 1 to ,retries
+      for ,success of-type boolean = nil
+      do
+      (let ((,txn
+	     (db-transaction-begin ,environment
+				   :parent ,parent
+				   :degree-2 (or ,degree-2 ,read-committed)
+				   :dirty-read (or ,dirty-read ,read-uncommitted)
+				   :txn-nosync ,txn-nosync
+				   :txn-nowait ,txn-nowait
+				   :txn-sync ,txn-sync)))
+	(declare (type pointer-void ,txn)
+		 (dynamic-extent ,txn))
+	(let ((,result
+	       (let ((*current-transaction* ,txn))
+		 (declare (special *current-transaction*)
+			  (dynamic-extent *current-transaction*))
+		 (catch 'transaction
+		   (unwind-protect
+			(prog1 (progn , at body)
+			  (setq ,success t)
+			  (db-transaction-commit :transaction ,txn 
+						 :txn-nosync ,txn-nosync
+						 :txn-sync ,txn-sync))
+		     (unless ,success 
+		       (db-transaction-abort :transaction ,txn)))))))
+	  (unless (and (eq ,result ,txn) (not ,success))
+	    (return ,result))))
+      finally (error "Too many retries"))))	       
+|#
--- /project/elephant/cvsroot/elephant/src/db-bdb/berkeley-db.lisp	2007/01/31 22:24:16	1.6
+++ /project/elephant/cvsroot/elephant/src/db-bdb/berkeley-db.lisp	2007/02/02 23:51:58	1.7
@@ -72,6 +72,9 @@
 
   )
 
+(defmacro txn-default (dvar)
+  `(if ,dvar ,dvar +NULL-VOID+))
+
 ;;
 ;; Constants and Flags
 ;; eventually write a macro which generates a custom flag function.
@@ -132,6 +135,8 @@
 (defconstant DB_FIRST		      7)
 (defconstant DB_GET_BOTH	      8)
 (defconstant DB_GET_BOTH_RANGE	     10)
+(defconstant DB_KEYFIRST	     13)
+(defconstant DB_KEYLAST		     14)
 (defconstant DB_LAST		     15)
 (defconstant DB_NEXT		     16)
 (defconstant DB_NEXT_DUP	     17)
@@ -220,8 +225,6 @@
 ;; makes flags into keywords
 ;; makes keyword args, cstring wrappers
 
-(defvar *errno-buffer* (allocate-foreign-object :int 1))
-
 (eval-when (:compile-toplevel)
   (defun make-wrapper-args (args flags keys)
     (if (or flags keys)
@@ -404,7 +407,7 @@
   :returning :int)
 
 (wrap-errno db-env-open (dbenvp home flags mode)
-	    :flags (init-cdb init-lock init-log 
+	    :flags (auto-commit init-cdb init-lock init-log 
 		    init-mpool init-rep init-txn
 		    recover recover-fatal create
 		    lockdown private system-mem thread
@@ -423,7 +426,7 @@
 
 (wrap-errno db-env-dbremove (env transaction file database flags) 
 	    :flags (auto-commit)
-	    :keys ((transaction *current-transaction*)
+	    :keys ((transaction (txn-default *current-transaction*))
 		   (database +NULL-CHAR+))
 	    :cstrings (file database)
 	    :transaction transaction
@@ -440,7 +443,7 @@
 
 (wrap-errno db-env-dbrename (env transaction file database newname flags) 
 	    :flags (auto-commit)
-	    :keys ((transaction *current-transaction*)
+	    :keys ((transaction (txn-default *current-transaction*))
 		   (database +NULL-CHAR+))
 	    :cstrings (file database newname)
 	    :transaction transaction
@@ -535,7 +538,7 @@
 	    :flags (auto-commit create dirty-read read-uncommitted 
 				excl nommap rdonly thread truncate
 				)
-	    :keys ((transaction *current-transaction*)
+	    :keys ((transaction (txn-default *current-transaction*))
 		   (file +NULL-CHAR+)
 		   (database +NULL-CHAR+)
 		   (type DB-UNKNOWN)
@@ -584,7 +587,8 @@
   :returning :int)
 
 (wrap-errno db-truncate (db transaction flags) :flags (auto-commit) 
-	    :keys ((transaction *current-transaction*)) :outs 2
+	    :keys ((transaction (txn-default *current-transaction*))) 
+	    :outs 2
 	    :transaction transaction
 	    :documentation "Truncate (erase) a DB.")
 
@@ -625,8 +629,8 @@
   :returning :int)
 
 (defun db-get-key-buffered (db key-buffer-stream value-buffer-stream
-			    &key (transaction *current-transaction*)
-			    auto-commit get-both degree-2 read-committed
+			    &key (transaction (txn-default *current-transaction*))
+			    get-both degree-2 read-committed
 			    dirty-read read-uncommitted)
   "Get a key / value pair from a DB.  The key is encoded in
 a buffer-stream.  Space for the value is passed in as a
@@ -634,7 +638,7 @@
 decoding, or NIL if nothing was found."
   (declare (type pointer-void db transaction)
 	   (type buffer-stream key-buffer-stream value-buffer-stream)
-	   (type boolean auto-commit get-both degree-2 read-committed dirty-read read-uncommitted))
+	   (type boolean get-both degree-2 read-committed dirty-read read-uncommitted))
   (loop 
    for value-length fixnum = (buffer-stream-length value-buffer-stream)
    do
@@ -644,8 +648,7 @@
 			     (buffer-stream-size key-buffer-stream)
 			     (buffer-stream-buffer value-buffer-stream) 
 			     value-length
-			     (flags :auto-commit auto-commit
-				    :get-both get-both
+			     (flags :get-both get-both
 				    :degree-2 (or degree-2 read-committed)
 				    :dirty-read (or dirty-read read-uncommitted)))
      (declare (type fixnum result-size errno))
@@ -675,8 +678,8 @@
 
 (defun db-get-buffered (db key value-buffer-stream &key
 			(key-size (length key))
-			(transaction *current-transaction*)
-			auto-commit get-both degree-2 read-committed
+			(transaction (txn-default *current-transaction*))
+			get-both degree-2 read-committed
 			dirty-read read-uncommitted)
   "Get a key / value pair from a DB.  The key is passed as a
 string.  Space for the value is passed in as a
@@ -686,7 +689,7 @@
 	   (type string key)
 	   (type buffer-stream value-buffer-stream)
 	   (type fixnum key-size)
-	   (type boolean auto-commit get-both degree-2 read-committed 
+	   (type boolean get-both degree-2 read-committed 
 		 dirty-read read-uncommitted))
   (with-cstring (k key)
     (loop 
@@ -696,8 +699,7 @@
 	 (%db-get-buffered db transaction k key-size 
 			   (buffer-stream-buffer value-buffer-stream)
 			   value-length
-			   (flags :auto-commit auto-commit
-				  :get-both get-both
+			   (flags :get-both get-both
 				  :degree-2 (or degree-2 read-committed)
 				  :dirty-read (or dirty-read read-uncommitted)))
        (declare (type fixnum result-size errno))
@@ -715,8 +717,8 @@
 	 (t (error 'db-error :errno errno)))))))
 
 (defun db-get (db key &key (key-size (length key))
-	       (transaction *current-transaction*)
-	       auto-commit get-both degree-2 read-committed
+	       (transaction (txn-default *current-transaction*))
+	       get-both degree-2 read-committed
 	       dirty-read read-uncommitted)
   "Get a key / value pair from a DB.  The key is passed as a
 string, and the value is returned as a string.  If nothing
@@ -724,7 +726,7 @@
   (declare (type pointer-void db transaction)
 	   (type string key)
 	   (type fixnum key-size)
-	   (type boolean auto-commit get-both degree-2 read-committed
+	   (type boolean get-both degree-2 read-committed
 		 dirty-read read-uncommitted))
   (with-cstring (k key)
     (with-buffer-streams (value-buffer-stream)
@@ -735,8 +737,7 @@
 	   (%db-get-buffered db transaction k key-size 
 			     (buffer-stream-buffer value-buffer-stream)
 			     value-length
-			     (flags :auto-commit auto-commit
-				    :get-both get-both
+			     (flags :get-both get-both
 				    :degree-2 (or degree-2 read-committed)
 				    :dirty-read (or dirty-read read-uncommitted)))
 	 (declare (type fixnum result-size errno))
@@ -766,21 +767,21 @@
   :returning :int)
 
 (defun db-put-buffered (db key-buffer-stream value-buffer-stream
-			&key (transaction *current-transaction*) auto-commit
+			&key (transaction (txn-default *current-transaction*))
 			exists-error-p)
   "Put a key / value pair into a DB.  The pair are encoded
 in buffer-streams.  T on success, or nil if the key already
 exists and EXISTS-ERROR-P is NIL."
   (declare (type pointer-void db transaction)
 	   (type buffer-stream key-buffer-stream value-buffer-stream)
-	   (type boolean auto-commit exists-error-p))
+	   (type boolean exists-error-p))
   (let ((errno 
 	 (%db-put-buffered db transaction 
 			   (buffer-stream-buffer key-buffer-stream)
 			   (buffer-stream-size key-buffer-stream)
 			   (buffer-stream-buffer value-buffer-stream)
 			   (buffer-stream-size value-buffer-stream)
-			   (flags :auto-commit auto-commit))))
+			   0)))
     (declare (type fixnum errno))
     (cond ((= errno 0) t)
 	  ((and (= errno DB_KEYEXIST) (not exists-error-p))
@@ -800,15 +801,14 @@
   :returning :int)
 
 (wrap-errno db-put (db transaction key key-size value value-size flags)
-	    :flags (auto-commit)
+	    :flags ()
 	    :keys ((key-size (length key))
 		   (value-size (length value))
-		   (transaction *current-transaction*))
+		   (transaction (txn-default *current-transaction*)))
 	    :cstrings (key value)
 	    :declarations (declare (type pointer-void db transaction)
 				   (type string key value)
-				   (type fixnum key-size value-size)
-				   (type boolean auto-commit))
+				   (type fixnum key-size value-size))
 	    :transaction transaction
 	    :documentation   
 "Put a key / value pair into a DB.  The pair are strings.")
@@ -821,18 +821,17 @@
      (flags :unsigned-int))
   :returning :int)
 
-(defun db-delete-buffered  (db key-buffer-stream &key auto-commit 
-			    (transaction *current-transaction*))
+(defun db-delete-buffered  (db key-buffer-stream 
+			    &key (transaction (txn-default *current-transaction*)))
   "Delete a key / value pair from a DB.  The key is encoded
 in a buffer-stream.  T on success, NIL if the key wasn't
 found."
   (declare (type pointer-void db transaction) 
-	   (type buffer-stream key-buffer-stream)
-	   (type boolean auto-commit))
+	   (type buffer-stream key-buffer-stream))
   (let ((errno (%db-delete-buffered db transaction
 				    (buffer-stream-buffer key-buffer-stream)
 				    (buffer-stream-size key-buffer-stream)
-				    (flags :auto-commit auto-commit))))
+				    0)))
     (declare (type fixnum errno))
     (cond ((= errno 0) t)
 	  ((or (= errno DB_NOTFOUND) 
@@ -851,16 +850,16 @@
      (flags :unsigned-int))
   :returning :int)
 
-(defun db-delete (db key &key auto-commit (key-size (length key))
-		  (transaction *current-transaction*))
+(defun db-delete (db key &key (key-size (length key))
+		  (transaction (txn-default *current-transaction*)))
   "Delete a key / value pair from a DB.  The key is a
 string.  T on success, NIL if the key wasn't found."
   (declare (type pointer-void db transaction) (type string key)
-	   (type fixnum key-size) (type boolean auto-commit))
+	   (type fixnum key-size))
   (with-cstrings ((key key))
     (let ((errno
 	   (%db-delete db transaction key
-		       key-size (flags :auto-commit auto-commit))))
+		       key-size 0)))
       (declare (type fixnum errno))
       (cond ((= errno 0) t)
 	    ((or (= errno DB_NOTFOUND) 
@@ -881,7 +880,7 @@
   :returning :int)
 
 (defun db-delete-kv-buffered  (db key-buffer-stream value-buffer-stream
-			       &key (transaction *current-transaction*))
+			       &key (transaction (txn-default *current-transaction*)))
   "Delete a specific key / value pair from a DB with
 duplicates.  The key and value are encoded as
 buffer-streams.  T on success, NIL if the key / value pair
@@ -918,7 +917,7 @@
      (end-size :unsigned-int :out))
   :returning :int)
 
-(defun db-compact (db start stop end &key (transaction *current-transaction*)
+(defun db-compact (db start stop end &key (transaction (txn-default *current-transaction*))
 		   freelist-only free-space)
   (declare (type pointer-void db transaction)
 	   (type buffer-stream start stop)
@@ -956,20 +955,22 @@
      (errnop (* :int)))
   :returning :pointer-void)
 
-(defun db-cursor (db &key (transaction *current-transaction*)
+(defun db-cursor (db &key (transaction (txn-default *current-transaction*))
 		  degree-2 read-committed dirty-read read-uncommitted)
   "Create a cursor."
   (declare (type pointer-void db)
-	   (type boolean degree-2 read-committed dirty-read read-uncommitted)
-	   (type pointer-int *errno-buffer*))
-  (let* ((curs (%db-cursor db transaction (flags :degree-2 (or degree-2 read-committed)
-						 :dirty-read (or dirty-read read-uncommitted))
-			   *errno-buffer*))
-	 (errno (deref-array *errno-buffer* '(:array :int) 0)))
-    (declare (type pointer-void curs)
-	     (type fixnum errno))
-    (if (= errno 0) curs
-	(error 'db-error :errno errno))))
+	   (type boolean degree-2 read-committed dirty-read read-uncommitted))
+  (let ((errno-buffer (allocate-foreign-object :int 1)))
+    (declare (type pointer-int errno-buffer))
+    (let* ((curs (%db-cursor db transaction 
+			     (flags :degree-2 (or degree-2 read-committed)
+				    :dirty-read (or dirty-read read-uncommitted))
+			     errno-buffer))
+	   (errno (deref-array errno-buffer '(:array :int) 0)))
+      (declare (type pointer-void curs)
+	       (type fixnum errno))
+      (if (= errno 0) curs
+	  (error 'db-error :errno errno)))))
 
 (def-function ("db_cursor_close" %db-cursor-close)
     ((cursor :pointer-void))
@@ -1005,13 +1006,15 @@
 (defun db-cursor-duplicate (cursor &key (position t)) 
   "Duplicate a cursor."
   (declare (type pointer-void cursor))
-  (let* ((newc (%db-cursor-dup cursor (flags :position position) 
-			       *errno-buffer*))
-	 (errno (deref-array *errno-buffer* '(:array :int) 0)))
-    (declare (type pointer-void newc)
-	     (type fixnum errno))
-    (if (= errno 0) newc
-	(error 'db-error :errno errno))))
+  (let ((errno-buffer (allocate-foreign-object :int 1)))
+    (declare (type pointer-int errno-buffer))
+    (let* ((newc (%db-cursor-dup cursor (flags :position position) 
+				 errno-buffer))
+	   (errno (deref-array errno-buffer '(:array :int) 0)))
+      (declare (type pointer-void newc)
+	       (type fixnum errno))
+      (if (= errno 0) newc
+	  (error 'db-error :errno errno)))))
 
 (def-function ("db_cursor_get_raw" %db-cursor-get-key-buffered)
     ((cursor :pointer-void)
@@ -1377,35 +1380,35 @@
      (errno (* :int)))
   :returning :pointer-void)
 
-(defun db-transaction-begin (env &key (parent *current-transaction*)
+(defun db-transaction-begin (env &key parent
 			     degree-2 read-committed dirty-read read-uncommitted
 			     txn-nosync txn-nowait txn-sync)
   "Start a transaction.  Transactions may be nested."
   (declare (type pointer-void env parent)
 	   (type boolean degree-2 read-committed dirty-read read-uncommitted 
-		 txn-nosync txn-nowait txn-sync)
-	   (type pointer-int *errno-buffer*))
-  (let* ((txn
-	  (%db-txn-begin env parent
-			 (flags :degree-2 (or degree-2 read-committed)
-				:dirty-read (or dirty-read read-uncommitted)
-				:txn-nosync txn-nosync
-				:txn-nowait txn-nowait
-				:txn-sync txn-sync)
-			 *errno-buffer*))
-	 (errno (deref-array *errno-buffer* '(:array :int) 0)))
-    (declare (type pointer-void txn)
-	     (type fixnum errno))
-    (if (= errno 0) 
-	txn
-	(error 'db-error :errno errno))))
+		 txn-nosync txn-nowait txn-sync))
+  (let ((errno-buffer (allocate-foreign-object :int 1)))
+    (declare (type pointer-int errno-buffer))
+    (let* ((txn
+	    (%db-txn-begin env parent
+			   (flags :degree-2 (or degree-2 read-committed)
+				  :dirty-read (or dirty-read read-uncommitted)
+				  :txn-nosync txn-nosync
+				  :txn-nowait txn-nowait
+				  :txn-sync txn-sync)
+			   errno-buffer))
+	   (errno (deref-array errno-buffer '(:array :int) 0)))
+      (declare (type pointer-void txn)
+	       (type fixnum errno))
+      (if (= errno 0) 
+	  txn
+	  (error 'db-error :errno errno)))))
 
 (def-function ("db_txn_abort" %db-txn-abort)
     ((txn :pointer-void))
   :returning :int)
 
 (wrap-errno (db-transaction-abort %db-txn-abort) (transaction)
-	    :keys ((transaction *current-transaction*))
 	    :declarations (declare (type pointer-void transaction))
 	    :documentation "Abort a transaction.")
 
@@ -1415,106 +1418,18 @@
   :returning :int)
 
 (wrap-errno (db-transaction-commit %db-txn-commit) (transaction flags)
-	    :keys ((transaction *current-transaction*))
 	    :flags (txn-nosync txn-sync)
 	    :declarations (declare (type pointer-void transaction)
 				   (type boolean txn-nosync txn-sync))
 	    :documentation "Commit a transaction.")
 
-#|
-(defmacro with-transaction ((&key transaction environment
-				  (parent '*current-transaction*)
-				  (retries 100)
-				  dirty-read read-uncommitted 
-				  txn-nosync txn-nowait txn-sync)
-			    &body body)

[208 lines skipped]




More information about the Elephant-cvs mailing list