forked from ryszard/clsql
-
Notifications
You must be signed in to change notification settings - Fork 12
choose database for instance
UnwashedMeme edited this page Sep 13, 2010
·
2 revisions
(defgeneric choose-database-for-instance (object &optional database)
(:documentation "Used by the oodml functions to select which
database object to use. Chooses the database associated with the
object primarily, falls back to the database provided as an argument
or the *DEFAULT-DATABASE*."))
(defmethod choose-database-for-instance ((obj standard-db-object) &optional database)
"Determine which database connection to use for a standard-db-object.
Errs if none is available."
(or (find-if #'(lambda (db)
(and db (is-database-open db)))
(list (view-database obj)
database
*default-database*))
(signal-no-database-error nil)))
The existing behavior of objects is that they use whatever database is in their view-database slot. If however you wish to have a reference to an object around longer than you wish to hold the connection open this is then a problem.
Web server requests a db obj for a user, sticks that object in the user’s session and closes the connection (potentially returning it to the pool, or closing completely). Some time later the user makes a second request, the code pulls the obj out of session, modifies a slot and tries to save to the database. ERROR: that db connection is closed (or worse yet actively being used by some other thread).
We have the following override:
(defmethod choose-database-for-instance ((object standard-db-object) &optional database) (or database *default-database*))
and then (as part of the accel branch) all of the functions that interact with the object call
(choose-database-for-instance obj db-arg)
. I.e. any db object you pass into one of the functions will be used above all else, then the default-database, and that’s it. The only use the view-class slot holds is a marker that this object came from a database (as opposed to freshly created with make-instance).