Allow lambda expression as cast rules using functions.

Before that it was necessary to install a function in the lisp environment
either in the source itself in src/utils/transforms.lisp, or in a lisp file
loaded with --load-lisp-file (or -l for shorts).

While this could be good enough, sometimes a very simple combination of
existing features is required to transform a function and so doing some
level of lisp coding directly in the load command is a nice to have.

Fixes #961.
This commit is contained in:
Dimitri Fontaine 2019-05-08 18:58:36 +02:00
parent 6aa42ec68f
commit 7d2e5ae941
5 changed files with 27 additions and 2 deletions

View File

@ -141,7 +141,12 @@
(string (intern (string-upcase fname) :pgloader.transforms))
(symbol fname))))
(defrule cast-function (and kw-using maybe-qualified-function-name)
(defrule transform-expression sexp
(:lambda (sexp)
(eval sexp)))
(defrule cast-function (and kw-using (or maybe-qualified-function-name
transform-expression))
(:destructure (using symbol) (declare (ignore using)) symbol))
(defun fix-target-type (source target)

View File

@ -104,6 +104,7 @@
logical-to-boolean
db3-trim-string
db3-numeric-to-pgsql-numeric
db3-numeric-to-pgsql-integer
db3-date-to-pgsql-date))
@ -505,10 +506,17 @@
(defun db3-numeric-to-pgsql-numeric (value)
"DB3 numerics should be good to go, but might contain spaces."
(let ((trimmed-string (string-right-trim '(#\Space) value)))
(let ((trimmed-string (string-trim '(#\Space) value)))
(unless (string= "" trimmed-string)
trimmed-string)))
(defun db3-numeric-to-pgsql-integer (value)
"DB3 numerics should be good to go, but might contain spaces."
(when value
(let ((integer-or-nil (parse-integer value :junk-allowed t)))
(when integer-or-nil
(write-to-string integer-or-nil)))))
(defun db3-date-to-pgsql-date (value)
"Convert a DB3 date to a PostgreSQL date."
(when (and value (string/= "" value) (= 8 (length value)))

BIN
test/data/DNORDOC.DBF Normal file

Binary file not shown.

BIN
test/data/DNORDOC.DBT Normal file

Binary file not shown.

12
test/dbf-memo.load Normal file
View File

@ -0,0 +1,12 @@
LOAD DBF
FROM data/DNORDOC.DBF with encoding cp866
INTO postgresql:///pgloader
TARGET TABLE public.dnordoc
WITH truncate, create table, disable triggers
cast
column dnordoc.normdocid
to uuid
using (lambda (normdocid)
(empty-string-to-null (right-trim normdocid))),
column dnordoc.doctype to integer using db3-numeric-to-pgsql-integer;