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 "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")
(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)
("l" "numeric" "numeric(18,3)" 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
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
;;;
(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)
"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
@ -272,7 +281,7 @@ order by ordinal_position" dbname table-name)))
"tinytext" "mediumtext" "longtext")
:test #'string-equal)
collect nil into nulls
collect (format nil "`~a`" name) into cols
collect (get-column-sql-expression name type) into cols
when is-null
collect (format nil "`~a` is null" name) into cols and collect t into nulls
finally (return (values cols nulls))))

View File

@ -16,7 +16,8 @@
date-with-no-separator
tinyint-to-boolean
int-to-ip
ip-range))
ip-range
convert-mysql-point))
(defun intern-symbol (symbol-name)
(intern (string-upcase symbol-name)
@ -83,3 +84,14 @@
(let ((ip-start (int-to-ip (parse-integer start-integer-string)))
(ip-end (int-to-ip (parse-integer end-integer-string))))
(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)))