diff --git a/src/sources/sqlite.lisp b/src/sources/sqlite.lisp index 7e3aef5..6eeeb6d 100644 --- a/src/sources/sqlite.lisp +++ b/src/sources/sqlite.lisp @@ -17,7 +17,9 @@ ("double precision" . pgloader.transforms::float-to-string) ("numeric" . pgloader.transforms::float-to-string) ("text" . nil) - ("bytea" . pgloader.transforms::byte-vector-to-bytea)) + ("bytea" . pgloader.transforms::byte-vector-to-bytea) + ("timestamp" . pgloader.transforms::sqlite-timestamp-to-timestamp) + ("timestamptz" . pgloader.transforms::sqlite-timestamp-to-timestamp)) "Transformation functions to use when migrating from SQLite to PostgreSQL.") ;;; diff --git a/src/transforms.lisp b/src/transforms.lisp index 040e476..51a0e77 100644 --- a/src/transforms.lisp +++ b/src/transforms.lisp @@ -24,7 +24,8 @@ empty-string-to-null set-to-enum-array right-trim - byte-vector-to-bytea)) + byte-vector-to-bytea + sqlite-timestamp-to-timestamp)) ;;; @@ -197,3 +198,27 @@ (setf (aref bytea pos) (aref hex-digits high)) (setf (aref bytea (+ pos 1)) (aref hex-digits low))) finally (return bytea))))) + +(defun sqlite-timestamp-to-timestamp (date-string-or-integer) + (declare (type (or integer simple-string) date-string-or-integer)) + (when date-string-or-integer + (cond ((and (typep date-string-or-integer 'integer) + (= 0 date-string-or-integer)) + nil) + + ((typep date-string-or-integer 'integer) + ;; a non-zero integer is a year + (format nil "~a-01-01" date-string-or-integer)) + + ((stringp date-string-or-integer) + ;; default values are sent as strings + (let ((maybe-integer + (ignore-errors (parse-integer date-string-or-integer)))) + (cond ((and maybe-integer (= 0 maybe-integer)) + nil) + + (maybe-integer + (format nil "~a-01-01" maybe-integer)) + + (t + date-string-or-integer))))))) diff --git a/test/sqlite/sqlite.db b/test/sqlite/sqlite.db index 997fffc..f1f49f0 100644 Binary files a/test/sqlite/sqlite.db and b/test/sqlite/sqlite.db differ