Skip to content

Commit d1b5187

Browse files
committed
Add missing provenance file.
1 parent 7a784bf commit d1b5187

File tree

1 file changed

+65
-0
lines changed

1 file changed

+65
-0
lines changed

provenance.lisp

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
(in-package #:quicklisp-controller)
2+
3+
(defvar *provenance-context* nil
4+
"This variable is used to store provenance updates in progress.")
5+
6+
(defun serializable-provenance-object-p (object)
7+
(or (and (consp object)
8+
(every #'serializable-provenance-object-p object))
9+
(typep object '(or keyword string integer boolean))))
10+
11+
(defun utf8-decode (octets)
12+
(read-from-string (babel:octets-to-string octets :encoding :utf-8)))
13+
14+
(defun utf8-encode (object)
15+
(unless (serializable-provenance-object-p object)
16+
(error "Cannot serialize ~S" object))
17+
(babel:string-to-octets (prin1-to-string object) :encoding :utf-8))
18+
19+
(defun load-provenance-db (db-file)
20+
(let ((table (make-hash-table :test 'equal)))
21+
(when (probe-file db-file)
22+
(zcdb:map-cdb
23+
(lambda (raw-key raw-value)
24+
(let ((key (utf8-decode raw-key))
25+
(value (utf8-decode raw-value)))
26+
(setf (gethash key table) value)))
27+
db-file))
28+
table))
29+
30+
(defun save-provenance-db (table db-file)
31+
(zcdb:with-output-to-cdb (cdb db-file (make-pathname :type "cdb-tmp"
32+
:defaults db-file))
33+
(maphash (lambda (key value)
34+
(zcdb:add-record (utf8-encode key)
35+
(utf8-encode value)
36+
cdb))
37+
table)))
38+
39+
(defun call-with-provenance-context (db-file fun)
40+
(setf db-file (merge-pathnames db-file))
41+
(if *provenance-context*
42+
(if (equalp db-file (car *provenance-context*))
43+
(funcall fun)
44+
(error "Nested provenance context - ~S vs ~S"
45+
db-file
46+
(car *provenance-context*)))
47+
(let ((*provenance-context* (cons db-file
48+
(load-provenance-db db-file))))
49+
(multiple-value-prog1
50+
(funcall fun)
51+
(save-provenance-db (cdr *provenance-context*) db-file)))))
52+
53+
(defmacro with-provenance-context ((db-file) &body body)
54+
`(call-with-provenance-context ,db-file (lambda () ,@body)))
55+
56+
(defun ensure-provenance-context ()
57+
(unless *provenance-context*
58+
(error "No provenance context is in effect!"))
59+
(cdr *provenance-context*))
60+
61+
(defun save-provenance (project key &rest plist &key &allow-other-keys)
62+
(let ((table (ensure-provenance-context)))
63+
(push (list key plist) (gethash project table))
64+
plist))
65+

0 commit comments

Comments
 (0)