forked from dimitri/pgloader
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement user-defined casting rules support for DB3.
The casting support for DB3 was hand-crafted and didn't get upgraded to using the current CAST grammar and facilities, for no other reasons than lack of time and interest. It so happens what implementing it now fixes two bug reports. Bug dimitri#938 is about conversion defaulting to "not null" column, and that's due to the usage of the internal pgloader catalogs where the target column's nullable field is NIL by default, which doesn't make much sense. With support for user-defined casting rules, the default is nullable columns, so that's kind of a free fix. Fixes dimitri#927. Fixes dimitri#938.
- Loading branch information
Showing
6 changed files
with
88 additions
and
59 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,72 @@ | ||
;;; | ||
;;; Tools to handle MySQL data type casting rules | ||
;;; | ||
|
||
(in-package :pgloader.source.db3) | ||
|
||
;;; | ||
;;; The default DB3 Type Casting Rules | ||
;;; | ||
(defparameter *db3-default-cast-rules* | ||
`((:source (:type "C") | ||
:target (:type "text") | ||
:using db3-trim-string) | ||
|
||
(:source (:type "N") | ||
:target (:type "numeric") | ||
:using db3-numeric-to-pgsql-numeric) | ||
|
||
(:source (:type "L") | ||
:target (:type "boolean") | ||
:using logical-to-boolean) | ||
|
||
(:source (:type "D") | ||
:target (:type "date") | ||
:using db3-date-to-pgsql-date) | ||
|
||
(:source (:type "M") | ||
:target (:type "text") | ||
:using db3-trim-string)) | ||
"Data Type Casting rules to migrate from DB3 to PostgreSQL") | ||
|
||
(defstruct (db3-field | ||
(:constructor make-db3-field (name type length))) | ||
name type length default (nullable t) extra) | ||
|
||
(defmethod cast ((field db3-field) &key table) | ||
"Return the PostgreSQL type definition given the DB3 one." | ||
(let ((table-name (table-name table))) | ||
(with-slots (name type length default nullable extra) field | ||
(apply-casting-rules table-name name type type default nullable extra)))) | ||
|
||
;;; | ||
;;; Transformation functions | ||
;;; | ||
(declaim (inline logical-to-boolean | ||
db3-trim-string | ||
db3-numeric-to-pgsql-numeric | ||
db3-date-to-pgsql-date)) | ||
|
||
(defun logical-to-boolean (value) | ||
"Convert a DB3 logical value to a PostgreSQL boolean." | ||
(if (string= value "?") nil value)) | ||
|
||
(defun db3-trim-string (value) | ||
"DB3 Strings a right padded with spaces, fix that." | ||
(string-right-trim '(#\Space) value)) | ||
|
||
(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))) | ||
(unless (string= "" trimmed-string) | ||
trimmed-string))) | ||
|
||
(defun db3-date-to-pgsql-date (value) | ||
"Convert a DB3 date to a PostgreSQL date." | ||
(when (and value (string/= "" value) (= 8 (length value))) | ||
(let ((year (parse-integer (subseq value 0 4) :junk-allowed t)) | ||
(month (parse-integer (subseq value 4 6) :junk-allowed t)) | ||
(day (parse-integer (subseq value 6 8) :junk-allowed t))) | ||
(when (and year month day) | ||
(format nil "~4,'0d-~2,'0d-~2,'0d" year month day))))) | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters