001package ca.uhn.fhir.jpa.migrate.taskdef;
002
003/*-
004 * #%L
005 * HAPI FHIR Server - SQL Migration
006 * %%
007 * Copyright (C) 2014 - 2023 Smile CDR, Inc.
008 * %%
009 * Licensed under the Apache License, Version 2.0 (the "License");
010 * you may not use this file except in compliance with the License.
011 * You may obtain a copy of the License at
012 *
013 *      http://www.apache.org/licenses/LICENSE-2.0
014 *
015 * Unless required by applicable law or agreed to in writing, software
016 * distributed under the License is distributed on an "AS IS" BASIS,
017 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
018 * See the License for the specific language governing permissions and
019 * limitations under the License.
020 * #L%
021 */
022
023import ca.uhn.fhir.i18n.Msg;
024import ca.uhn.fhir.jpa.migrate.DriverTypeEnum;
025
026/**
027 * Helper to extract database information about supported migrations.
028 */
029public class MetadataSource {
030
031        /**
032         * Does this database support index operations without write-locking the table?
033         */
034        public boolean isOnlineIndexSupported(DriverTypeEnum.ConnectionProperties theConnectionProperties) {
035
036                switch (theConnectionProperties.getDriverType()) {
037                        case POSTGRES_9_4:
038                        case COCKROACHDB_21_1:
039                                return true;
040                        case MSSQL_2012:
041                                String mssqlEdition = getEdition(theConnectionProperties);
042                                return mssqlEdition.startsWith("Enterprise");
043                        case ORACLE_12C:
044                                String oracleEdition = getEdition(theConnectionProperties);
045                                return oracleEdition.contains("Enterprise");
046                        default:
047                                return false;
048                }
049        }
050
051        /**
052         * Get the MS Sql Server or Oracle Server edition.  Other databases are not supported yet.
053         *
054         * @param theConnectionProperties the database to inspect
055         * @return the edition string (e.g. Standard, Enterprise, Developer, etc.)
056         */
057        private String getEdition(DriverTypeEnum.ConnectionProperties theConnectionProperties) {
058                final String result;
059                if (theConnectionProperties.getDriverType() == DriverTypeEnum.MSSQL_2012) {
060                        result = theConnectionProperties.newJdbcTemplate().queryForObject("SELECT SERVERPROPERTY ('edition')", String.class);
061                } else if (theConnectionProperties.getDriverType() == DriverTypeEnum.ORACLE_12C) {
062                        result = theConnectionProperties.newJdbcTemplate().queryForObject("SELECT BANNER FROM v$version WHERE banner LIKE 'Oracle%'", String.class);
063                } else {
064                        throw new UnsupportedOperationException(Msg.code(2084) + "We only know about MSSQL editions.");
065                }
066                return result;
067        }
068}