Rework the summary handling in LOAD FROM ARCHIVE commands.

This commit is contained in:
Dimitri Fontaine 2013-09-30 16:04:01 +02:00
parent 9c1592c4eb
commit 32d183efa5
3 changed files with 69 additions and 59 deletions

View File

@ -205,47 +205,37 @@ Finally returns how many rows where read and processed."
(escape cl-csv:*quote-escape*)
(null-as "\\N"))
"Copy data from CSV file FILENAME into PostgreSQL DBNAME.TABLE-NAME"
(let* ((report-header (null *state*))
(let* ((summary (null *state*))
(*state* (or *state* (pgloader.utils:make-pgstate)))
(lp:*kernel* (make-kernel 2))
(channel (lp:make-channel))
(dataq (lq:make-queue :fixed-capacity 4096))
(filename (get-absolute-pathname filename-or-regex)))
;; statistics
(when report-header (report-header))
(pgstate-add-table *state* dbname table-name)
(report-table-name table-name)
(with-stats-collection (dbname table-name :state *state* :summary summary)
(log-message :notice "COPY ~a.~a" dbname table-name)
(lp:submit-task channel
;; this function update :read stats
#'pgloader.csv:copy-to-queue table-name filename dataq
:fields fields
:columns columns
:encoding encoding
:skip-lines skip-lines
:separator separator
:quote quote
:escape escape
:null-as null-as)
(multiple-value-bind (res secs)
(timing
(lp:submit-task channel
;; this function update :read stats
#'pgloader.csv:copy-to-queue table-name filename dataq
:fields fields
:columns columns
:encoding encoding
:skip-lines skip-lines
:separator separator
:quote quote
:escape escape
:null-as null-as)
;; and start another task to push that data from the queue to PostgreSQL
(lp:submit-task channel
;; this function update :rows stats
#'pgloader.pgsql:copy-from-queue dbname table-name dataq
:truncate truncate
:transforms transforms)
;; and start another task to push that data from the queue to PostgreSQL
(lp:submit-task channel
;; this function update :rows stats
#'pgloader.pgsql:copy-from-queue dbname table-name dataq
:truncate truncate
:transforms transforms)
;; now wait until both the tasks are over
(loop for tasks below 2 do (lp:receive-result channel))
(lp:end-kernel))
;; report stats!
(declare (ignore res))
(pgstate-incf *state* table-name :secs secs)
(report-pgtable-stats *state* table-name))))
;; now wait until both the tasks are over
(loop for tasks below 2 do (lp:receive-result channel)
finally (lp:end-kernel)))))
(defun import-database (dbname
&key

View File

@ -1230,39 +1230,56 @@ Here's a quick description of the format we're parsing here:
(destructuring-bind (&key host port user password dbname &allow-other-keys)
pg-db-uri
`(lambda ()
(let* ((archive-file
(let* ((state-before (pgloader.utils:make-pgstate))
(*state* (pgloader.utils:make-pgstate))
(state-finally (pgloader.utils:make-pgstate))
(archive-file
,(destructuring-bind (kind url) source
(ecase kind
(:http `(pgloader.archive:http-fetch-file ,url))
(:http `(with-stats-collection
(,dbname "download" :state state-before)
(pgloader.archive:http-fetch-file ,url)))
(:filename url))))
(*csv-path-root* (pgloader.archive:expand-archive archive-file))
(*csv-path-root*
(with-stats-collection (,dbname "extract" :state state-before)
(pgloader.archive:expand-archive archive-file)))
(*pgconn-host* ,host)
(*pgconn-port* ,port)
(*pgconn-user* ,user)
(*pgconn-pass* ,password)
(*state* (pgloader.utils:make-pgstate)))
(*pgconn-pass* ,password))
(progn
;; before block
(with-pgsql-transaction (,dbname)
(loop for command in ',before
do
(log-message :notice command)
(pgsql-execute command :client-min-messages :error)))
(with-stats-collection (,dbname "before load" :state state-before)
(with-pgsql-transaction (,dbname)
(loop for command in ',before
do
(log-message :notice command)
(pgsql-execute command :client-min-messages :error))))
;; import from files block
(report-header)
,@(loop for command in commands
collect `(funcall ,command))
(report-pgstate-stats *state* "Total import time")
;; finally block
(with-pgsql-transaction (,dbname)
(loop for command in ',finally
for first = t then nil
when first do (format t "~&")
do
(log-message :notice command)
(pgsql-execute command :client-min-messages :error))))))))))
(with-stats-collection (,dbname "finally" :state state-finally)
(with-pgsql-transaction (,dbname)
(loop for command in ',finally
do
(log-message :notice command)
(pgsql-execute command :client-min-messages :error))))
;; reporting
(report-summary :state state-before :footer nil)
(format t pgloader.utils::*header-line*)
(report-summary :state *state* :header nil :footer nil)
(format t pgloader.utils::*header-line*)
(report-summary :state state-finally :header nil :footer nil)
;; add to the grand total the other sections
(incf (pgloader.utils::pgstate-secs *state*)
(+ (pgloader.utils::pgstate-secs state-before)
(pgloader.utils::pgstate-secs state-finally)))
;; and report the Grand Total
(report-pgstate-stats *state* "Total import time"))))))))
;;;
@ -1381,6 +1398,8 @@ LOAD FROM http:///tapoueh.org/db.t
"))
(defun test-parsing-load-from-archive ()
"Use either http://pgsql.tapoueh.org/temp/foo.zip
or /Users/dim/Downloads/GeoLiteCity-latest.zip"
(parse-command "
LOAD FROM ARCHIVE /Users/dim/Downloads/GeoLiteCity-latest.zip
INTO postgresql://dim@localhost:54393/dim

View File

@ -253,13 +253,14 @@
given DBNAME and TABLE-NAME"
(let ((result (gensym "result"))
(secs (gensym "secs")))
`(progn
(pgstate-add-table ,pgstate ,dbname ,table-name)
(multiple-value-bind (,result ,secs)
(timing ,@forms)
(if ,use-result-as-rows
(pgstate-incf ,pgstate ,table-name :rows ,result :secs ,secs)
(pgstate-incf ,pgstate ,table-name :secs ,secs)))
`(prog2
(pgstate-add-table ,pgstate ,dbname ,table-name)
(multiple-value-bind (,result ,secs)
(timing ,@forms)
(if ,use-result-as-rows
(pgstate-incf ,pgstate ,table-name :rows ,result :secs ,secs)
(pgstate-incf ,pgstate ,table-name :secs ,secs))
,result)
(when ,summary (report-summary)))))
;;;