mirror of
https://github.com/dimitri/pgloader.git
synced 2025-08-07 14:56:59 +02:00
112 lines
3.9 KiB
Common Lisp
112 lines
3.9 KiB
Common Lisp
;;;
|
|
;;; Global state maintenance, which includes statistics about each target of
|
|
;;; the load: number of lines read, imported and number of errors found
|
|
;;; along the way.
|
|
;;;
|
|
(in-package :pgloader.utils)
|
|
|
|
;;;
|
|
;;; Data Structures to maintain information about loading state
|
|
;;;
|
|
(defstruct pgtable
|
|
name
|
|
(read 0 :type fixnum) ; how many rows did we read
|
|
(rows 0 :type fixnum) ; how many rows did we write
|
|
(errs 0 :type fixnum) ; how many errors did we see
|
|
(secs 0.0 :type float) ; how many seconds did it take
|
|
reject-data reject-logs) ; files where to find reject data
|
|
|
|
(defstruct pgstate
|
|
(tables (make-hash-table :test 'equal))
|
|
(tabnames nil) ; we want to keep the ordering
|
|
(read 0 :type fixnum)
|
|
(rows 0 :type fixnum)
|
|
(errs 0 :type fixnum)
|
|
(secs 0.0 :type float))
|
|
|
|
(defun pgstate-get-table (pgstate name)
|
|
(gethash name (pgstate-tables pgstate)))
|
|
|
|
(defun pgstate-add-table (pgstate dbname table-name)
|
|
"Instanciate a new pgtable structure to hold our stats, and return it."
|
|
(or (pgstate-get-table pgstate table-name)
|
|
(let* ((table (setf (gethash table-name (pgstate-tables pgstate))
|
|
(make-pgtable :name table-name)))
|
|
(reject-dir (merge-pathnames (format nil "~a/" dbname) *root-dir*))
|
|
(data-pathname (make-pathname :defaults reject-dir
|
|
:name table-name :type "dat"))
|
|
(logs-pathname (make-pathname :defaults reject-dir
|
|
:name table-name :type "log")))
|
|
|
|
;; maintain the ordering
|
|
(push table-name (pgstate-tabnames pgstate))
|
|
|
|
;; create the per-database directory if it does not exists yet
|
|
(ensure-directories-exist reject-dir)
|
|
|
|
;; rename the existing files if there are some
|
|
(when (probe-file data-pathname)
|
|
(with-open-file (data data-pathname
|
|
:direction :output
|
|
:if-exists :rename
|
|
:if-does-not-exist nil)))
|
|
|
|
(when (probe-file logs-pathname)
|
|
(with-open-file (logs logs-pathname
|
|
:direction :output
|
|
:if-exists :rename
|
|
:if-does-not-exist nil)))
|
|
|
|
;; set the properties to the right pathnames
|
|
(setf (pgtable-reject-data table) data-pathname
|
|
(pgtable-reject-logs table) logs-pathname)
|
|
table)))
|
|
|
|
(defun pgstate-setf (pgstate name &key read rows errs secs)
|
|
(let ((pgtable (pgstate-get-table pgstate name)))
|
|
(when read
|
|
(setf (pgtable-read pgtable) read)
|
|
(incf (pgstate-read pgstate) read))
|
|
(when rows
|
|
(setf (pgtable-rows pgtable) rows)
|
|
(incf (pgstate-rows pgstate) rows))
|
|
(when errs
|
|
(setf (pgtable-errs pgtable) errs)
|
|
(incf (pgstate-errs pgstate) errs))
|
|
(when secs
|
|
(setf (pgtable-secs pgtable) secs)
|
|
(incf (pgstate-secs pgstate) secs))
|
|
pgtable))
|
|
|
|
(defun pgstate-incf (pgstate name &key read rows errs secs)
|
|
(let ((pgtable (pgstate-get-table pgstate name)))
|
|
(when read
|
|
(incf (pgtable-read pgtable) read)
|
|
(incf (pgstate-read pgstate) read))
|
|
(when rows
|
|
(incf (pgtable-rows pgtable) rows)
|
|
(incf (pgstate-rows pgstate) rows))
|
|
(when errs
|
|
(incf (pgtable-errs pgtable) errs)
|
|
(incf (pgstate-errs pgstate) errs))
|
|
(when secs
|
|
(incf (pgtable-secs pgtable) secs)
|
|
(incf (pgstate-secs pgstate) secs))
|
|
pgtable))
|
|
|
|
(defun pgstate-decf (pgstate name &key read rows errs secs)
|
|
(let ((pgtable (pgstate-get-table pgstate name)))
|
|
(when read
|
|
(decf (pgtable-read pgtable) read)
|
|
(decf (pgstate-read pgstate) read))
|
|
(when rows
|
|
(decf (pgtable-rows pgtable) rows)
|
|
(decf (pgstate-rows pgstate) rows))
|
|
(when errs
|
|
(decf (pgtable-errs pgtable) errs)
|
|
(decf (pgstate-errs pgstate) errs))
|
|
(when secs
|
|
(decf (pgtable-secs pgtable) secs)
|
|
(decf (pgstate-secs pgstate) secs))
|
|
pgtable))
|