##// END OF EJS Templates
Properly check deftable options
Properly check deftable options

File last commit:

r0:21cd5557 default
r4:f8b202e4 default
Show More
cache.lisp
71 lines | 2.5 KiB | text/x-common-lisp | CommonLispLexer
(in-package mito-transactions.dev)
;;;; Cache for `mito` objects with the main purpose of avoiding
;;;; several instances of the same dao which are not `eq` to each
;;;; other. Cached objects are only removed when they are GC'ed so
;;;; next time they will have other identity but it's not a problem
;;;; beause there would be no previous objects to EQ against.
(defmethod mito.dao.mixin:make-dao-instance ((obj cached-dao-class) &key &allow-other-keys)
"This method is called on creation of dao instances loaded from the DB. "
(declare (ignore obj))
(maybe-lock
(let ((*ignore-transaction* t))
(do-cache (call-next-method)))))
(defmethod mito:insert-dao ((obj cached-dao))
(maybe-lock
(call-next-method)
(setf (gethash (mito:object-id obj) (class-cache obj)) obj)
obj))
(defmethod mito:delete-dao ((obj cached-dao))
(maybe-lock
(remhash (mito:object-id obj) (class-cache (class-of obj)))
(call-next-method)))
(defmethod mito:delete-by-values ((class cached-dao-class) &rest fields-and-values)
(maybe-lock
;; We need their IDs to remove from the cache
(let ((objs (apply #'mito:retrieve-dao class fields-and-values)))
(call-next-method)
(dolist (obj objs)
(remhash (mito:object-id obj) (class-cache (class-of obj))))
(values))))
(defgeneric class-cache (class)
(:method ((class cached-dao-class))
(slot-value class 'cache))
(:method ((obj cached-dao))
(class-cache (class-of obj)))
(:method ((classname symbol))
(class-cache (find-class classname))))
(defun get-dao (class id)
"Fetch an object directly from the cache, only check the db if it's not cached."
(maybe-lock
(or (gethash id (class-cache class))
(do-cache (first (mito:select-dao class (sxql:where (:= :id id))))))))
(defun get-dao-from-cache-only (class id)
"Fetch an object directly from the cache, return NIL if it's not cached."
(maybe-lock
(gethash id (class-cache class))))
(defun do-cache (obj)
(when obj
(let ((cache (class-cache obj)))
(sif (gethash (mito:object-id obj) cache)
(copy-fields it obj)
(setf it obj)))))
(defun copy-fields (to from)
(when (local-time:timestamp> (mito:object-updated-at from)
(mito:object-updated-at to))
(let ((*ignore-transaction* t)
(slot-names (mapcar #'c2mop:slot-definition-name
(mito.class.table:table-column-slots (class-of from)))))
(dolist (slot-name slot-names)
(setf (slot-value to slot-name) (slot-value from slot-name)))))
to)