Add support for MySQL point datatype, where we need using astext(col).

This commit is contained in:
Dimitri Fontaine 2013-10-06 21:01:11 +02:00
parent 922aa22d64
commit 5a235de5c5
3 changed files with 31 additions and 4 deletions

View File

@ -121,7 +121,12 @@
(:source (:type "year") :target (:type "integer")) (:source (:type "year") :target (:type "integer"))
(:source (:type "enum") (:source (:type "enum")
:target (:type ,#'cast-enum))) :target (:type ,#'cast-enum))
;; geometric data types, just POINT for now
(:source (:type "point")
:target (:type "point")
:using pgloader.transforms::convert-mysql-point))
"Data Type Casting rules to migrate from MySQL to PostgreSQL") "Data Type Casting rules to migrate from MySQL to PostgreSQL")
(defvar *cast-rules* nil "Specific casting rules added in the command.") (defvar *cast-rules* nil "Specific casting rules added in the command.")
@ -328,7 +333,8 @@ that would be int and int(7) or varchar and varchar(25)."
("k" "bigint" "bigint(20)" nil nil nil) ("k" "bigint" "bigint(20)" nil nil nil)
("l" "numeric" "numeric(18,3)" nil nil nil) ("l" "numeric" "numeric(18,3)" nil nil nil)
("m" "decimal" "decimal(15,5)" nil nil nil) ("m" "decimal" "decimal(15,5)" nil nil nil)
("n" "timestamp" "timestamp" "CURRENT_TIMESTAMP" "NO" "on update CURRENT_TIMESTAMP")))) ("n" "timestamp" "timestamp" "CURRENT_TIMESTAMP" "NO" "on update CURRENT_TIMESTAMP")
("o" "point" "point" nil "YES" nil))))
(loop (loop
for (name dtype ctype nullable default extra) in columns for (name dtype ctype nullable default extra) in columns

View File

@ -258,6 +258,15 @@ GROUP BY table_name, index_name;" dbname)))
;;; ;;;
;;; Map a function to each row extracted from MySQL ;;; Map a function to each row extracted from MySQL
;;; ;;;
(defun get-column-sql-expression (name type)
"Return per-TYPE SQL expression to use given a column NAME.
Mostly we just use the name, but in case of POINT we need to use
astext(name)."
(case (intern (string-upcase type) "KEYWORD")
(:point (format nil "astext(`~a`) as `~a`" name name))
(t (format nil "`~a`" name))))
(defun get-column-list-with-is-nulls (dbname table-name) (defun get-column-list-with-is-nulls (dbname table-name)
"We can't just SELECT *, we need to cater for NULLs in text columns ourselves. "We can't just SELECT *, we need to cater for NULLs in text columns ourselves.
This function assumes a valid connection to the MySQL server has been This function assumes a valid connection to the MySQL server has been
@ -272,7 +281,7 @@ order by ordinal_position" dbname table-name)))
"tinytext" "mediumtext" "longtext") "tinytext" "mediumtext" "longtext")
:test #'string-equal) :test #'string-equal)
collect nil into nulls collect nil into nulls
collect (format nil "`~a`" name) into cols collect (get-column-sql-expression name type) into cols
when is-null when is-null
collect (format nil "`~a` is null" name) into cols and collect t into nulls collect (format nil "`~a` is null" name) into cols and collect t into nulls
finally (return (values cols nulls)))) finally (return (values cols nulls))))

View File

@ -16,7 +16,8 @@
date-with-no-separator date-with-no-separator
tinyint-to-boolean tinyint-to-boolean
int-to-ip int-to-ip
ip-range)) ip-range
convert-mysql-point))
(defun intern-symbol (symbol-name) (defun intern-symbol (symbol-name)
(intern (string-upcase symbol-name) (intern (string-upcase symbol-name)
@ -83,3 +84,14 @@
(let ((ip-start (int-to-ip (parse-integer start-integer-string))) (let ((ip-start (int-to-ip (parse-integer start-integer-string)))
(ip-end (int-to-ip (parse-integer end-integer-string)))) (ip-end (int-to-ip (parse-integer end-integer-string))))
(concatenate 'simple-base-string ip-start "-" ip-end))) (concatenate 'simple-base-string ip-start "-" ip-end)))
(defun convert-mysql-point (mysql-point-as-string)
"Transform the MYSQL-POINT-AS-STRING into a suitable representation for
PostgreSQL.
Input: \"POINT(48.5513589 7.6926827)\" ; that's using astext(column)
Output: (48.5513589,7.6926827)"
(when mysql-point-as-string
(let* ((point (subseq mysql-point-as-string 5)))
(setf (aref point (position #\Space point)) #\,)
point)))