(ns metabase.db.liquibase.mysql (:require [clojure.string :as str]) (:import (liquibase.database Database) (liquibase.database.core MySQLDatabase) (liquibase.sql Sql UnparsedSql) (liquibase.sqlgenerator SqlGeneratorFactory) (liquibase.sqlgenerator.core AddColumnGenerator CreateTableGenerator SetColumnRemarksGenerator) (liquibase.structure DatabaseObject))) | |
(set! *warn-on-reflection* true) | |
(defn- mysql? [database] (instance? MySQLDatabase database)) | |
Custom generator for | (defn- column-remarks-generator ^SetColumnRemarksGenerator [] (proxy [SetColumnRemarksGenerator] [] (getPriority [] (let [^SetColumnRemarksGenerator this this] (inc (proxy-super getPriority)))) (supports [statement database] (let [^SetColumnRemarksGenerator this this] (and (proxy-super supports statement database) (mysql? database)))) (generateSql [_statement _database _sql-generator-chain] (into-array Sql [])))) |
we need a separate ADD COLUMN generator in case an ADD COLUMN migration is being on launch without any CREATE TABLE migrations happening before it | |
It seems like Liquibase actually ignores the | (defn- set-mysql-current-datetime-function! [^Database database] (.setCurrentDateTimeFunction database "current_timestamp(6)")) |
We need generators for both ADD COLUMN and for CREATE TABLE because if we have say just one new migration that is one type or the other then we need to have that specific generator call [[set-mysql-current-datetime-function!]]. TODO -- we should probably add a generate for ADD DEFAULT VALUE too. I assumed this didn't work so for a lot of
MySQL/MariaDB migrations that add defaults values to | |
Custom generator for This uses | (defn- add-column-generator ^AddColumnGenerator [] (proxy [AddColumnGenerator] [] (getPriority [] (let [^AddColumnGenerator this this] (inc (proxy-super getPriority)))) (supports [statement database] (let [^AddColumnGenerator this this] (and (proxy-super supports statement database) (mysql? database)))) (generateSql [statement database sql-generator-chain] (set-mysql-current-datetime-function! database) (let [^AddColumnGenerator this this] (proxy-super generateSql statement database sql-generator-chain))))) |
Custom generator for
| (defn- create-table-generator ^CreateTableGenerator [] (proxy [CreateTableGenerator] [] (getPriority [] (let [^CreateTableGenerator this this] (inc (proxy-super getPriority)))) (supports [statement database] (let [^CreateTableGenerator this this] (and (proxy-super supports statement database) (mysql? database)))) (generateSql [statement ^Database database sql-generator-chain] (set-mysql-current-datetime-function! database) (let [^CreateTableGenerator this this] (into-array Sql (map (fn [^Sql sql] (if-not (str/starts-with? (.toSql sql) "CREATE TABLE") sql (UnparsedSql. (str (.toSql sql) " ENGINE InnoDB CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;") (into-array DatabaseObject (.getAffectedDatabaseObjects sql))))) (proxy-super generateSql statement database sql-generator-chain))))))) |
Register our custom MySQL SQL generators. | (defn register-mysql-generators! [] (doto (SqlGeneratorFactory/getInstance) (.register (column-remarks-generator)) (.register (add-column-generator)) (.register (create-table-generator)))) |