001/*- 002 * #%L 003 * HAPI FHIR Server - SQL Migration 004 * %% 005 * Copyright (C) 2014 - 2025 Smile CDR, Inc. 006 * %% 007 * Licensed under the Apache License, Version 2.0 (the "License"); 008 * you may not use this file except in compliance with the License. 009 * You may obtain a copy of the License at 010 * 011 * http://www.apache.org/licenses/LICENSE-2.0 012 * 013 * Unless required by applicable law or agreed to in writing, software 014 * distributed under the License is distributed on an "AS IS" BASIS, 015 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 016 * See the License for the specific language governing permissions and 017 * limitations under the License. 018 * #L% 019 */ 020package ca.uhn.fhir.jpa.migrate.taskdef; 021 022import ca.uhn.fhir.i18n.Msg; 023import ca.uhn.fhir.jpa.migrate.DriverTypeEnum; 024 025import java.util.HashMap; 026import java.util.Map; 027 028public final class ColumnTypeToDriverTypeToSqlType { 029 030 private ColumnTypeToDriverTypeToSqlType() {} 031 032 static Map<ColumnTypeEnum, Map<DriverTypeEnum, String>> myColumnTypeToDriverTypeToSqlType = new HashMap<>(); 033 034 static { 035 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.H2_EMBEDDED, "integer"); 036 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.DERBY_EMBEDDED, "integer"); 037 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MARIADB_10_1, "integer"); 038 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MYSQL_5_7, "integer"); 039 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.MSSQL_2012, "int"); 040 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.ORACLE_12C, "number(10,0)"); 041 setColumnType(ColumnTypeEnum.INT, DriverTypeEnum.POSTGRES_9_4, "int4"); 042 043 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.H2_EMBEDDED, "smallint"); 044 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.DERBY_EMBEDDED, "smallint"); 045 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.MARIADB_10_1, "smallint"); 046 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.MYSQL_5_7, "smallint"); 047 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.MSSQL_2012, "smallint"); 048 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.ORACLE_12C, "number(5,0)"); 049 setColumnType(ColumnTypeEnum.SMALLINT, DriverTypeEnum.POSTGRES_9_4, "int2"); 050 051 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.H2_EMBEDDED, "tinyint"); 052 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.DERBY_EMBEDDED, "smallint"); 053 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.MARIADB_10_1, "tinyint"); 054 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.MYSQL_5_7, "tinyint"); 055 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.MSSQL_2012, "smallint"); 056 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.ORACLE_12C, "number(3,0)"); 057 setColumnType(ColumnTypeEnum.TINYINT, DriverTypeEnum.POSTGRES_9_4, "int2"); 058 059 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.H2_EMBEDDED, "float"); 060 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.DERBY_EMBEDDED, "float"); 061 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MARIADB_10_1, "float"); 062 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MYSQL_5_7, "float"); 063 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.MSSQL_2012, "float"); 064 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.ORACLE_12C, "float"); 065 setColumnType(ColumnTypeEnum.FLOAT, DriverTypeEnum.POSTGRES_9_4, "float"); 066 067 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.H2_EMBEDDED, "double"); 068 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.DERBY_EMBEDDED, "double"); 069 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MARIADB_10_1, "double precision"); 070 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MYSQL_5_7, "double precision"); 071 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.MSSQL_2012, "double precision"); 072 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.ORACLE_12C, "double precision"); 073 setColumnType(ColumnTypeEnum.DOUBLE, DriverTypeEnum.POSTGRES_9_4, "double precision"); 074 075 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.H2_EMBEDDED, "bigint"); 076 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.DERBY_EMBEDDED, "bigint"); 077 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MARIADB_10_1, "bigint"); 078 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MYSQL_5_7, "bigint"); 079 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.MSSQL_2012, "bigint"); 080 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.ORACLE_12C, "number(19,0)"); 081 setColumnType(ColumnTypeEnum.LONG, DriverTypeEnum.POSTGRES_9_4, "int8"); 082 083 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.H2_EMBEDDED, "varchar(?)"); 084 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.DERBY_EMBEDDED, "varchar(?)"); 085 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MARIADB_10_1, "varchar(?)"); 086 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MYSQL_5_7, "varchar(?)"); 087 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.MSSQL_2012, "varchar(?)"); 088 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.ORACLE_12C, "varchar2(? char)"); 089 setColumnType(ColumnTypeEnum.STRING, DriverTypeEnum.POSTGRES_9_4, "varchar(?)"); 090 091 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.H2_EMBEDDED, "timestamp"); 092 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.DERBY_EMBEDDED, "timestamp"); 093 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MARIADB_10_1, "datetime(6)"); 094 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MYSQL_5_7, "datetime(6)"); 095 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.MSSQL_2012, "datetime2"); 096 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.ORACLE_12C, "timestamp"); 097 setColumnType(ColumnTypeEnum.DATE_TIMESTAMP, DriverTypeEnum.POSTGRES_9_4, "timestamp"); 098 099 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.H2_EMBEDDED, "date"); 100 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.DERBY_EMBEDDED, "date"); 101 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MARIADB_10_1, "date"); 102 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MYSQL_5_7, "date"); 103 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.MSSQL_2012, "date"); 104 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.ORACLE_12C, "date"); 105 setColumnType(ColumnTypeEnum.DATE_ONLY, DriverTypeEnum.POSTGRES_9_4, "date"); 106 107 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.H2_EMBEDDED, "boolean"); 108 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.DERBY_EMBEDDED, "boolean"); 109 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MSSQL_2012, "bit"); 110 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MARIADB_10_1, "bit"); 111 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.ORACLE_12C, "number(1,0)"); 112 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.POSTGRES_9_4, "boolean"); 113 setColumnType(ColumnTypeEnum.BOOLEAN, DriverTypeEnum.MYSQL_5_7, "bit"); 114 115 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.H2_EMBEDDED, "blob"); 116 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.DERBY_EMBEDDED, "blob"); 117 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MARIADB_10_1, "longblob"); 118 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MYSQL_5_7, "longblob"); 119 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.ORACLE_12C, "blob"); 120 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.POSTGRES_9_4, "oid"); 121 setColumnType(ColumnTypeEnum.BLOB, DriverTypeEnum.MSSQL_2012, "varbinary(MAX)"); 122 123 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.H2_EMBEDDED, "clob"); 124 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.DERBY_EMBEDDED, "clob(100000)"); 125 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MARIADB_10_1, "longtext"); 126 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MYSQL_5_7, "longtext"); 127 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.ORACLE_12C, "clob"); 128 setColumnType( 129 ColumnTypeEnum.CLOB, 130 DriverTypeEnum.POSTGRES_9_4, 131 "oid"); // the PG driver will write oid into a `text` column 132 setColumnType(ColumnTypeEnum.CLOB, DriverTypeEnum.MSSQL_2012, "varchar(MAX)"); 133 134 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.H2_EMBEDDED, "clob"); 135 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.DERBY_EMBEDDED, "clob"); 136 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.MARIADB_10_1, "longtext"); 137 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.MYSQL_5_7, "longtext"); 138 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.ORACLE_12C, "clob"); 139 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.POSTGRES_9_4, "text"); 140 setColumnType(ColumnTypeEnum.TEXT, DriverTypeEnum.MSSQL_2012, "varchar(MAX)"); 141 142 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.H2_EMBEDDED, "blob"); 143 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.DERBY_EMBEDDED, "blob"); 144 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.MARIADB_10_1, "longblob"); 145 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.MYSQL_5_7, "longblob"); 146 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.ORACLE_12C, "blob"); 147 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.POSTGRES_9_4, "bytea"); 148 setColumnType(ColumnTypeEnum.BINARY, DriverTypeEnum.MSSQL_2012, "varbinary(MAX)"); 149 150 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.H2_EMBEDDED, "numeric(38,2)"); 151 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.DERBY_EMBEDDED, "decimal(31,2)"); 152 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.MARIADB_10_1, "decimal(38,2)"); 153 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.MYSQL_5_7, "decimal(38,2)"); 154 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.ORACLE_12C, "number(38,2)"); 155 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.POSTGRES_9_4, "numeric(38,2)"); 156 setColumnType(ColumnTypeEnum.BIG_DECIMAL, DriverTypeEnum.MSSQL_2012, "numeric(38,2)"); 157 } 158 159 public static Map<ColumnTypeEnum, Map<DriverTypeEnum, String>> getColumnTypeToDriverTypeToSqlType() { 160 return myColumnTypeToDriverTypeToSqlType; 161 } 162 163 private static void setColumnType( 164 ColumnTypeEnum theColumnType, DriverTypeEnum theDriverType, String theColumnTypeSql) { 165 Map<DriverTypeEnum, String> columnSqlType = 166 myColumnTypeToDriverTypeToSqlType.computeIfAbsent(theColumnType, k -> new HashMap<>()); 167 if (columnSqlType.containsKey(theDriverType)) { 168 throw new IllegalStateException(Msg.code(65) + "Duplicate key: " + theDriverType); 169 } 170 columnSqlType.put(theDriverType, theColumnTypeSql); 171 } 172 173 public static String toBooleanValue(DriverTypeEnum theDriverType, Boolean theBoolean) { 174 switch (theDriverType) { 175 case H2_EMBEDDED: 176 case DERBY_EMBEDDED: 177 case POSTGRES_9_4: 178 return theBoolean.toString(); 179 default: 180 return theBoolean ? "1" : "0"; 181 } 182 } 183}