Revert "hold my beer, let's remove *DB-LOCK*"
This reverts commit f6561a64a3
.
This commit is contained in:
parent
2a1e7303d0
commit
2f4e78bc8c
35
sqlite.lisp
35
sqlite.lisp
|
@ -2,6 +2,8 @@
|
||||||
|
|
||||||
(defvar *db* nil
|
(defvar *db* nil
|
||||||
"Connection to the database.")
|
"Connection to the database.")
|
||||||
|
(defvar *db-lock* (bt:make-recursive-lock "sqlite3 lock")
|
||||||
|
"Lock for *DB*.")
|
||||||
(defparameter *default-database-path* "data.sqlite3"
|
(defparameter *default-database-path* "data.sqlite3"
|
||||||
"Default path to the SQLite database file.")
|
"Default path to the SQLite database file.")
|
||||||
(defvar *prepared-statements* nil
|
(defvar *prepared-statements* nil
|
||||||
|
@ -18,11 +20,12 @@
|
||||||
|
|
||||||
(defun connect-database (&optional (path *default-database-path*))
|
(defun connect-database (&optional (path *default-database-path*))
|
||||||
"Establish a connection to the database."
|
"Establish a connection to the database."
|
||||||
(setf *db* (sqlite:connect path))
|
(bt:with-recursive-lock-held (*db-lock*)
|
||||||
(run-pragmas)
|
(setf *db* (sqlite:connect path))
|
||||||
(loop for sym in *prepared-statements*
|
(run-pragmas)
|
||||||
do (eval `(setf ,sym nil)))
|
(loop for sym in *prepared-statements*
|
||||||
(setf *prepared-statements* nil))
|
do (eval `(setf ,sym nil)))
|
||||||
|
(setf *prepared-statements* nil)))
|
||||||
|
|
||||||
(defmacro prepared-statement (statement)
|
(defmacro prepared-statement (statement)
|
||||||
"Caches the creation of a prepared statement with SQL text STATEMENT.
|
"Caches the creation of a prepared statement with SQL text STATEMENT.
|
||||||
|
@ -38,11 +41,12 @@ In other words, prepares STATEMENT once, then returns the prepared statement aft
|
||||||
|
|
||||||
(defmacro with-prepared-statement ((name statement) &body forms)
|
(defmacro with-prepared-statement ((name statement) &body forms)
|
||||||
"Evaluates FORMS, binding a prepared statement with SQL text STATEMENT to NAME, and ensuring it is reset when control is transferred."
|
"Evaluates FORMS, binding a prepared statement with SQL text STATEMENT to NAME, and ensuring it is reset when control is transferred."
|
||||||
`(let ((,name (prepared-statement ,statement)))
|
`(bt:with-recursive-lock-held (*db-lock*)
|
||||||
(multiple-value-prog1
|
(let ((,name (prepared-statement ,statement)))
|
||||||
(unwind-protect
|
(multiple-value-prog1
|
||||||
(progn ,@forms)
|
(unwind-protect
|
||||||
(ignore-errors (sqlite:reset-statement ,name))))))
|
(progn ,@forms)
|
||||||
|
(ignore-errors (sqlite:reset-statement ,name)))))))
|
||||||
|
|
||||||
(defmacro with-prepared-statements (statements &body forms)
|
(defmacro with-prepared-statements (statements &body forms)
|
||||||
"Like WITH-PREPARED-STATEMENT, but takes multiple statements."
|
"Like WITH-PREPARED-STATEMENT, but takes multiple statements."
|
||||||
|
@ -50,11 +54,12 @@ In other words, prepares STATEMENT once, then returns the prepared statement aft
|
||||||
collect `(,name (prepared-statement ,statement))))
|
collect `(,name (prepared-statement ,statement))))
|
||||||
(reset-forms (loop for (name statement) in statements
|
(reset-forms (loop for (name statement) in statements
|
||||||
collect `(ignore-errors (sqlite:reset-statement ,name)))))
|
collect `(ignore-errors (sqlite:reset-statement ,name)))))
|
||||||
`(let (,@let-forms)
|
`(bt:with-recursive-lock-held (*db-lock*)
|
||||||
(multiple-value-prog1
|
(let (,@let-forms)
|
||||||
(unwind-protect
|
(multiple-value-prog1
|
||||||
(progn ,@forms))
|
(unwind-protect
|
||||||
(ignore-errors (progn ,@reset-forms))))))
|
(progn ,@forms))
|
||||||
|
(ignore-errors (progn ,@reset-forms)))))))
|
||||||
|
|
||||||
(defmacro column-values (statement)
|
(defmacro column-values (statement)
|
||||||
"Returns the values in the current row of the STATEMENT."
|
"Returns the values in the current row of the STATEMENT."
|
||||||
|
|
Loading…
Reference in a new issue