Implement support for MySQL linestring data type.

This data type is now converted automatically to a PostgreSQL path data
type, using the open path notation with square brackets:

  https://www.postgresql.org/docs/current/static/datatype-geometric.html#AEN7103

Fix #445.
This commit is contained in:
Dimitri Fontaine 2017-08-15 15:26:06 +02:00
parent 20a85055f4
commit e21ce09ad7
3 changed files with 27 additions and 4 deletions

View File

@ -141,7 +141,11 @@
(:source (:type "point") (:source (:type "point")
:target (:type "point") :target (:type "point")
:using pgloader.transforms::convert-mysql-point)) :using pgloader.transforms::convert-mysql-point)
(:source (:type "linestring")
:target (:type "path")
:using pgloader.transforms::convert-mysql-linestring))
"Data Type Casting rules to migrate from MySQL to PostgreSQL") "Data Type Casting rules to migrate from MySQL to PostgreSQL")

View File

@ -339,9 +339,10 @@
Mostly we just use the name, but in case of POINT we need to use Mostly we just use the name, but in case of POINT we need to use
astext(name)." astext(name)."
(case (intern (string-upcase type) "KEYWORD") (case (intern (string-upcase type) "KEYWORD")
(:geometry (format nil "astext(`~a`) as `~a`" name name)) (:geometry (format nil "astext(`~a`) as `~a`" name name))
(:point (format nil "astext(`~a`) as `~a`" name name)) (:point (format nil "astext(`~a`) as `~a`" name name))
(t (format nil "`~a`" name)))) (:linestring (format nil "astext(`~a`) as `~a`" name name))
(t (format nil "`~a`" name))))
(defun get-column-list (dbname table-name) (defun get-column-list (dbname table-name)
"Some MySQL datatypes have a meaningless default output representation, we "Some MySQL datatypes have a meaningless default output representation, we

View File

@ -187,6 +187,24 @@
(setf (aref point (position #\Space point)) #\,) (setf (aref point (position #\Space point)) #\,)
point))) point)))
(defun convert-mysql-linestring (mysql-linestring-as-string)
"Transform the MYSQL-POINT-AS-STRING into a suitable representation for
PostgreSQL.
Input: \"LINESTRING(-87.87342467651445 45.79684462673078,-87.87170806274479 45.802110434248966)\" ; that's using astext(column)
Output: [(-87.87342467651445,45.79684462673078),(-87.87170806274479,45.802110434248966)]"
(when mysql-linestring-as-string
(let* ((data (subseq mysql-linestring-as-string
11
(- (length mysql-linestring-as-string) 1))))
(with-output-to-string (s)
(write-string "[" s)
(loop :for first := t :then nil
:for point :in (split-sequence:split-sequence #\, data)
:for (x y) := (split-sequence:split-sequence #\Space point)
:do (format s "~:[,~;~](~a,~a)" first x y))
(write-string "]" s)))))
(defun integer-to-string (integer-string) (defun integer-to-string (integer-string)
"Transform INTEGER-STRING parameter into a proper string representation of "Transform INTEGER-STRING parameter into a proper string representation of
it. In particular be careful of quoted-integers, thanks to SQLite default it. In particular be careful of quoted-integers, thanks to SQLite default