diff --git a/pgloader.1.md b/pgloader.1.md index 4acaab1..57a495a 100644 --- a/pgloader.1.md +++ b/pgloader.1.md @@ -402,6 +402,16 @@ The `csv` format command accepts the following clauses and options: This character is used as the *field separator* when reading the `CSV` data. + - *lines terminated by* + + Takes a single character as argument, which must be found inside + single quotes, and might be given as the printable character itself, + the special value \t to denote a tabulation character, or `0x` then + an hexadecimal value read as the ascii code for the character. + + This character is used to recognize *end-of-line* condition when + reading the `CSV` data. + - *SET* This clause allows to specify session parameters to be set for all the diff --git a/src/parser.lisp b/src/parser.lisp index dc589f3..5465c06 100644 --- a/src/parser.lisp +++ b/src/parser.lisp @@ -1290,6 +1290,12 @@ load database (declare (ignore fields )) sep))) +(defrule option-lines-terminated-by (and kw-lines kw-terminated kw-by separator) + (:lambda (term) + (destructuring-bind (lines terminated by sep) term + (declare (ignore lines terminated by)) + (cons :newline sep)))) + (defrule option-keep-unquoted-blanks (and kw-keep kw-unquoted kw-blanks) (:constant (cons :trim-blanks nil))) @@ -1298,6 +1304,7 @@ load database (defrule csv-option (or option-truncate option-skip-header + option-lines-terminated-by option-fields-not-enclosed option-fields-enclosed-by option-fields-escaped-by diff --git a/src/sources/csv.lisp b/src/sources/csv.lisp index 43f2622..5333be4 100644 --- a/src/sources/csv.lisp +++ b/src/sources/csv.lisp @@ -18,6 +18,9 @@ (separator :accessor csv-separator ; CSV separator :initarg :separator ; :initform #\Tab) ; + (newline :accessor csv-newline ; CSV line ending + :initarg :newline ; + :initform #\Newline) (quote :accessor csv-quote ; CSV quoting :initarg :quote ; :initform cl-csv:*quote*) ; @@ -100,8 +103,9 @@ :escape (csv-escape csv) :unquoted-empty-string-is-nil t :quoted-empty-string-is-nil nil - :trim-outer-whitespace (csv-trim-blanks csv)) - ((or cl-csv:csv-parse-error type-error) (condition) + :trim-outer-whitespace (csv-trim-blanks csv) + :newline (csv-newline csv)) + ((or cl-csv:csv-parse-error) (condition) (progn (log-message :error "~a" condition) (pgstate-setf *state* (target csv) :errs -1)))))))))) diff --git a/test/csv-newline.load b/test/csv-newline.load new file mode 100644 index 0000000..c4f8d6c --- /dev/null +++ b/test/csv-newline.load @@ -0,0 +1,14 @@ +LOAD CSV + FROM INLINE + INTO postgresql:///pgloader?lines (f1, f2, f3) + WITH truncate, + fields optionally enclosed by '"', + fields escaped by double-quote, + fields terminated by '¦', + lines terminated by '¶' + + BEFORE LOAD DO + $$ drop table if exists lines; $$, + $$ create table if not exists lines (id serial, f1 text, f2 text, f3 text); $$; + +plop¦bar¦foo¶plip¦second line¦bar¶