From e3327e6292db5deef60e288f68566a8114b4ca34 Mon Sep 17 00:00:00 2001 From: Dmitry Kalyanov Date: Sun, 10 May 2009 10:05:28 +0400 Subject: [PATCH] Keep track of prepared statements instead of using sqlite3_next_stmt --- sqlite-ffi.lisp | 7 +------ sqlite.lisp | 21 +++++++++++---------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/sqlite-ffi.lisp b/sqlite-ffi.lisp index 1c8bbe1..1e6f9b2 100644 --- a/sqlite-ffi.lisp +++ b/sqlite-ffi.lisp @@ -29,8 +29,7 @@ :sqlite3-bind-blob :destructor-transient :destructor-static - :sqlite3-last-insert-rowid - :sqlite3-next-stmt)) + :sqlite3-last-insert-rowid)) (in-package :sqlite-ffi) @@ -193,7 +192,3 @@ (defcfun sqlite3-last-insert-rowid :int64 (db p-sqlite3)) - -(defcfun sqlite3-next-stmt p-sqlite3-stmt - (db p-sqlite3) - (stmt p-sqlite3-stmt)) \ No newline at end of file diff --git a/sqlite.lisp b/sqlite.lisp index 4d961ee..4b8952a 100644 --- a/sqlite.lisp +++ b/sqlite.lisp @@ -25,7 +25,8 @@ (defclass sqlite-handle () ((handle :accessor handle) (database-path :accessor database-path) - (cache :accessor cache)) + (cache :accessor cache) + (statements :initform nil :accessor sqlite-handle-statements)) (:documentation "Class that encapsulates the connection to the database. Use connect and disconnect.")) (defmethod initialize-instance :after ((object sqlite-handle) &key (database-path ":memory:") &allow-other-keys) @@ -45,9 +46,10 @@ (defun disconnect (handle) "Disconnects the given HANDLE from the database. All further operations on the handle are invalid." (sqlite.cache:purge-cache (cache handle)) - (iter (for p-stmt = (sqlite-ffi:sqlite3-next-stmt (handle handle) (cffi:null-pointer))) - (until (cffi:null-pointer-p p-stmt)) - (sqlite-ffi:sqlite3-finalize p-stmt)) + (iter (with statements = (copy-list (sqlite-handle-statements handle))) + (declare (dynamic-extent statements)) + (for statement in statements) + (really-finalize-statement statement)) (let ((error-code (sqlite-ffi:sqlite3-close (handle handle)))) (unless (eq error-code :ok) (error "Received error code ~A when trying to close ~A (connected to ~A)" error-code handle (database-path handle))))) @@ -92,24 +94,23 @@ SQL may have some positional (not named) parameters specified with question mark Example: select name from users where id = ?" - #+nil(make-instance 'sqlite-statement :db db :sql sql) (or (sqlite.cache:get-from-cache (cache db) sql) - (make-instance 'sqlite-statement :db db :sql sql))) + (let ((statement (make-instance 'sqlite-statement :db db :sql sql))) + (push statement (sqlite-handle-statements db)) + statement))) (defun really-finalize-statement (statement) + (setf (sqlite-handle-statements (db statement)) + (delete statement (sqlite-handle-statements (db statement)))) (sqlite-ffi:sqlite3-finalize (handle statement))) (defun finalize-statement (statement) "Finalizes the statement and signals that associated resources may be released. Note: does not immediately release resources because statements are cached." - #+nil(really-finalize-statement statement) (progn (let ((error-code (sqlite-ffi:sqlite3-reset (handle statement)))) (unless (eq error-code :ok) (error "When resetting statement ~A (sql: ~A), error ~A (~A)" statement (sql statement) error-code (sqlite-ffi:sqlite3-errmsg (handle (db statement)))))) - #+nil(let ((error-code (sqlite-ffi:sqlite3-clear-bindings (handle statement)))) - (unless (eq error-code :ok) - (error "When resetting statement ~A (sql: ~A), error ~A (~A)" statement (sql statement) error-code (sqlite-ffi:sqlite3-errmsg (handle (db statement)))))) (sqlite.cache:put-to-cache (cache (db statement)) (sql statement) statement))) (defun step-statement (statement) -- 2.11.4.GIT