[Refactored database-range-view clinton@unknownlamer.org**20080205213031 * New query-view classes moved to lame-web library * Rebuild show lists on top of query-view ] { hunk ./src/packages.lisp 74 - (:use :common-lisp :ucw :ucw-compat :golf-db :golf-util :golf-config) + (:use :common-lisp :ucw :ucw-compat :lame-web + :golf-db :golf-util :golf-config) hunk ./src/web-common.lisp 86 -;; database driven range-view -;; Fetches current window and such using a query protocol -;; Should be renamed to query-range-view with a query-view parent and -;; cached-query-view child class. The methods should maybe be renamed -;; as well. -;; Min/max support could perhaps be put into a mixin? It is probably -;; not worth the effort -(defcomponent database-range-view () - ((offset :initarg :offset - :accessor range-view.offset - :initform 0 - :backtrack t) - (window-size :accessor range-view.window-size :initform 20 - :initarg :window-size) - ;; should total-items be cached? - (total-items :accessor range-view.total-items) - (reverse :accessor reversep :initform nil :initarg :reverse) - (minimum :initarg :min :initform nil) - (maximum :initarg :max :initform nil))) - -(defcomponent cached-database-range-view (database-range-view) - ((current-window :initform nil :accessor range-view.current-window))) - -(defgeneric range-view.window-count (range)) - -(defgeneric range-view.current-window (range)) - -(defgeneric range-view-get-instances (range-view lower upper - &key limit skip from-end) - (:documentation "lower and upper are exclusive limits")) - -(defgeneric range-view-total-instances (range-view) - (:documentation "Ask the database for the total number of - instances. By default this value is cached by - range-view.total-items")) - -(defgeneric range-view-count-instances (range-view min max) - (:documentation "Count items in database between min and max")) - -(defmethod initialize-instance :after ((r database-range-view) - &key &allow-other-keys) - (setf (range-view.offset r) (range-view.offset r))) - -(defmethod range-view.current-window ((range database-range-view)) - (let ((limit (range-view.window-size range)) - (skip (* (range-view.window-size range) - (range-view.offset range)))) - (mapcar - (lambda (i) (cons (incf skip) i)) - (with-slots (minimum maximum) range - (if (reversep range) - (range-view-get-instances range minimum maximum - :from-end t :limit limit :skip skip) - (range-view-get-instances range minimum maximum - :from-end nil :limit limit :skip skip)))))) - -(defmethod range-view-total-instances ((range database-range-view)) - (with-slots (minimum maximum) range - (range-view-count-instances range minimum maximum))) - -(defmethod range-view.current-window-items ((range database-range-view)) - (mapcar #'cdr (range-view.current-window range))) - -(defmethod range-view.total-items ((range database-range-view)) - (if (slot-boundp range 'total-items) - (slot-value range 'total-items) - (setf (slot-value range 'total-items) (range-view-total-instances range)))) - -(defmethod range-view.have-previous-p ((range database-range-view)) - (not (zerop (range-view.offset range)))) - -(defmethod range-view.have-next-p ((range database-range-view)) - (let ((base-item (car (last (range-view.current-window-items range))))) - (with-slots (minimum maximum) range - (if (reversep range) - (range-view-get-instances range minimum base-item :limit 1 :from-end t) - (range-view-get-instances range base-item maximum :limit 1))))) - -(defmethod range-view.window-count ((range database-range-view)) - (ceiling (1- (/ (range-view.total-items range) - (range-view.window-size range))))) - -(defmethod/cc scroll-start ((range database-range-view)) - (setf (range-view.offset range) 0)) - -(defmethod/cc scroll-end ((range database-range-view)) - (setf (range-view.offset range) (range-view.window-count range))) - -(defmethod/cc scroll-forward ((range database-range-view) &optional (n 1)) - (let ((offset (+ n (range-view.offset range)))) - (if (> offset (range-view.window-count range)) - (scroll-end range) - (setf (range-view.offset range) offset)))) - -(defmethod/cc scroll-backward ((range database-range-view) &optional (n 1)) - (let ((offset (- (range-view.offset range) n))) - (if (<= offset 0) - (scroll-start range) - (setf (range-view.offset range) offset)))) - -(defmethod/cc scroll-to-page ((range database-range-view) &optional (n 1)) - (cond ((< offset 0) (scroll-start range)) - ((> offset (range-view.window-count range)) (scroll-end range)) - (t (setf range-view.offset range) n))) - -;; cached database range view -(defun range-view-get-forward (range old-offset new-offset) - (let ((base-item (car (last (range-view.current-window-items range)))) - (limit (range-view.window-size range)) - (skip (if (= new-offset old-offset) - 0 - (* (range-view.window-size range) - (1- (- new-offset old-offset)))))) - (with-slots (minimum maximum) range - (if (reversep range) - (range-view-get-instances range minimum (or base-item maximum) - :from-end t :limit limit :skip skip) - (range-view-get-instances range (or base-item minimum) maximum - :from-end nil :limit limit :skip skip))))) - -(defun range-view-get-backward (range old-offset new-offset) - (let ((base-item (car (range-view.current-window-items range))) - (limit (range-view.window-size range)) - (skip (* (range-view.window-size range) - (1- (- old-offset new-offset))))) - (with-slots (minimum maximum) range - (if (reversep range) - (range-view-get-instances range (or base-item minimum) maximum - :from-end nil :limit limit :skip skip) - (range-view-get-instances range minimum (or base-item maximum) - :from-end t :limit limit :skip skip))))) - -(defun range-view-reload-instances (range old-offset new-offset) - - (let ((start (* (range-view.window-size range) - (range-view.offset range)))) - (setf - (range-view.current-window range) - (mapcar - (lambda (i) (cons (incf start) i)) - (cond - ((>= new-offset old-offset) - (range-view-get-forward range old-offset new-offset)) - ((< new-offset old-offset) - (nreverse - (range-view-get-backward range old-offset new-offset)))))))) - -(defmethod (setf range-view.offset) :around (new-offset - (range cached-database-range-view)) - (assert (>= new-offset 0) (new-offset)) - (let ((old-offset (range-view.offset range))) - (call-next-method) - (range-view-reload-instances range old-offset new-offset) - new-offset)) - hunk ./src/web-common.lisp 154 -(defcomponent show-list (show-viewer) +(defcomponent show-list (show-viewer query-view) hunk ./src/web-common.lisp 159 +(defmethod query-view-get-instances ((view show-list) + lower upper + &rest keys) + (let ((lower (if (typep lower 'radio-show) (show-date lower) lower)) + (upper (if (typep upper 'radio-show) (show-date upper) upper))) + (apply #'get-shows-by 'show-date lower upper + keys))) + +(defmethod query-view-count-instances ((view show-list) min max) + (golf-db::count-shows-by 'show-date min max)) + hunk ./src/web-common.lisp 171 - (elephant:get-instances-by-class 'radio-show)) + (lame-web::current-items list)) hunk ./src/web-common.lisp 191 -(defcomponent ranged-show-list (cached-database-range-view show-list) +(defcomponent ranged-show-list (cached-query-paged-view-mixin + query-ranged-view-mixin + show-list) hunk ./src/web-common.lisp 206 -(defmethod range-view-get-instances ((range ranged-show-list) - lower upper - &rest keys) - (let ((lower (if (typep lower 'radio-show) (show-date lower) lower)) - (upper (if (typep upper 'radio-show) (show-date upper) upper))) - (apply #'get-shows-by 'show-date (and lower (1+ lower)) (and upper (1- upper)) - keys))) - -(defmethod range-view-count-instances ((range ranged-show-list) min max) - (golf-db::count-shows-by 'show-date min max)) - hunk ./src/web-common.lisp 207 - (range-view.current-window-items range)) + (lame-web::current-items range)) hunk ./src/web-common.lisp 214 - (1+ (range-view.offset self)) - (1+ (range-view.window-count self))) + (1+ (page-offset self)) + (1+ (page-count self))) hunk ./src/web-common.lisp 217 - (if (range-view.have-previous-p self) + (if (have-previous-page-p self) hunk ./src/web-common.lisp 222 - (if (range-view.have-next-p self) + (if (have-next-page-p self) }