pgloader/utils.lisp
2013-02-07 00:04:12 +01:00

69 lines
1.9 KiB
Common Lisp

;;;
;;; Random utilities
;;;
(defpackage #:pgloader.utils
(:use #:cl)
(:export #:report-header
#:report-table-name
#:report-results
#:report-footer
#:format-interval
#:timing))
(in-package :pgloader.utils)
;;;
;;; Timing Macro
;;;
(defun elapsed-time-since (start)
"Return how many seconds ticked between START and now"
(/ (- (get-internal-real-time) start)
internal-time-units-per-second))
(defmacro timing (&body forms)
"return both how much real time was spend in body and its result"
(let ((start (gensym))
(end (gensym))
(result (gensym)))
`(let* ((,start (get-internal-real-time))
(,result (progn ,@forms))
(,end (get-internal-real-time)))
(values ,result (/ (- ,end ,start) internal-time-units-per-second)))))
;;;
;;; Timing Formating
;;;
(defun format-interval (seconds &optional (stream t))
"Output the number of seconds in a human friendly way"
(multiple-value-bind (years months days hours mins secs millisecs)
(date:decode-interval (date:encode-interval :second seconds))
(format
stream
"~:[~*~;~d years ~]~:[~*~;~d months ~]~:[~*~;~d days ~]~:[~*~;~dh~]~:[~*~;~dm~]~d.~ds"
(< 0 years) years
(< 0 months) months
(< 0 days) days
(< 0 hours) hours
(< 0 mins) mins
secs (truncate millisecs))))
;;;
;;; Pretty print a report while doing bulk operations
;;;
(defun report-header ()
(format t "~&~30@a ~9@a ~9@a" "table name" "rows" "time")
(format t "~&------------------------------ --------- ---------"))
(defun report-table-name (table-name)
(format t "~&~30@a " table-name))
(defun report-results (rows seconds)
(format t "~9@a ~9@a" rows (format-interval seconds nil)))
(defun report-footer (legend rows seconds)
(format t "~&------------------------------ --------- ---------")
(format t "~&~30@a ~9@a ~9@a" legend
rows (format-interval seconds nil)))