package com.tesora.dve.upgrade; /* * #%L * Tesora Inc. * Database Virtualization Engine * %% * Copyright (C) 2011 - 2014 Tesora Inc. * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, version 3, * as published by the Free Software Foundation. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Affero General Public License for more details. * * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * #L% */ import java.util.ArrayList; import java.util.List; import java.util.Properties; import java.util.TreeMap; import com.tesora.dve.common.DBHelper; import com.tesora.dve.common.InformationCallback; import com.tesora.dve.common.PELogUtils; import com.tesora.dve.common.catalog.CatalogDAO; import com.tesora.dve.exceptions.PECodingException; import com.tesora.dve.exceptions.PEException; import com.tesora.dve.server.global.HostService; import com.tesora.dve.singleton.Singletons; import com.tesora.dve.sql.util.Functional; import com.tesora.dve.upgrade.versions.*; // these are the currently known version numbers. if we come across a catalog with an older version // number then we must dump and load. public class CatalogVersions { public enum CatalogVersionNumber { SHOW_SERVERS(new InfoSchemaServerTable(22)), TEMPLATE_MATCH(new MatchTemplateVersion(23)), CREATE_OPTIONS_VERSIONS(new CreateTableOptionsVersion(24)), ADD_PLUGINS_SUPPORT(new InfoSchemaUpgradeVersion(25)), RAW_PLANS(new RawPlans(26)), ADD_CHARSET_IDS(new AddCharsetIds(27)), INFO_SCHEMA_TYPE_CHANGES(new InfoSchemaTypeChanges(28)), MT_FKS(new MTForeignKeys(29)), ENCRYPT_PASSWORD(new EncryptPasswordsVersion(30)), ADAPTIVE_AUTOINCREMENT(new AdaptiveAutoIncrementVersion(31)), VIEWS(new AddViewsVersion(32)), REF_CONSTRAINT_SCHEMAS(new InfoSchemaUpgradeVersion(33)), USER_SECURITY(new UserSecurityVersion(34)), COLUMN_CARDINALITY(new ColumnCardinality(35)), REBRANDING(new RebrandingVersion(36)), ADD_COLLATION(new AddCollation(37)), ADD_TEMPLATE_MODE(new AddTemplateMode(38)), EXTRA_INFO_SCHEMA_COLUMNS_COLUMNS(new ExtraInfoSchemaColumnsColumns(39)), EXTERNAL_SERVICE_SHOW_CONFIG(new InfoSchemaUpgradeVersion(40)), TEMPORARY_TABLES(new UserlandTemporaryTables(41)), GLOBAL_VARIABLES(new GlobalVariablesVersion(42)), COLLATION_ID_TYPE(new InfoSchemaUpgradeVersion(43)), INFOSCHEMA_CAPITALIZATION(new InfoSchemaUpgradeVersion(44)), DIRECT_INFOSCHEMA(new DirectInfoSchema(45)), TRIGGERS(new TriggersVersion(46)), ADD_MISSING_COLLATIONS(new InfoSchemaUpgradeVersion(47)); private final CatalogVersion upgradeModule; private CatalogVersionNumber(CatalogVersion upgradeModule) { this.upgradeModule = upgradeModule; } public CatalogVersion getCatalogVersion() { return upgradeModule; } } private static final List<CatalogVersion> knownVersions = new ArrayList<CatalogVersion>(); // this is dependent on major release - we should update this after every major release // we maintain a separate variable rather than just testing on version number for release management reasons. private static final CatalogVersionNumber mustDumpAndLoadBefore = CatalogVersionNumber.SHOW_SERVERS; static { for(CatalogVersionNumber cvn : CatalogVersionNumber.values()) { knownVersions.add(cvn.getCatalogVersion()); } } static List<CatalogVersion> versionHistory = null; public static CatalogSchemaVersion getCurrentVersion() throws PEException { List<CatalogVersion> versions = getVersionHistory(); CatalogSchemaVersion csv = new CatalogSchemaVersion(versions.get(versions.size() - 1).getSchemaVersion(), PELogUtils.getBuildVersionString(false),"current"); return csv; } public static CatalogVersionNumber getOldestUpgradeSupported() { return mustDumpAndLoadBefore; } // throws ONLY IF the version doesn't match latest. this is the check we do at server startup. public static CatalogSchemaVersion catalogVersionCheck(Properties props) throws PEException { DBHelper helper = null; try { helper = new DBHelper(props); CatalogSchemaVersion current = getCurrentVersion(); helper.connect(); CatalogSchemaVersion persistentVersion = CatalogSchemaVersion.getPersistentVersion(helper); CatalogSchemaVersion.check(persistentVersion, current, mustDumpAndLoadBefore.getCatalogVersion()); return current; } finally { if(helper != null) helper.disconnect(); } } public static List<CatalogVersion> getVersionHistory() throws PEException { if (versionHistory == null) { TreeMap<Integer,CatalogVersion> versions = new TreeMap<Integer,CatalogVersion>(); for(CatalogVersion cv : knownVersions) { CatalogVersion already = versions.get(cv.getSchemaVersion()); if (already != null) throw new PEException("Duplicate version numbers in catalog upgrade"); versions.put(cv.getSchemaVersion(), cv); } versionHistory = Functional.toList(versions.values()); } return versionHistory; } public static void upgradeToLatest(Properties props, InformationCallback stdout) throws PEException { //make sure we have host services started, but no catalog. if (Singletons.lookup(HostService.class) == null){ throw new PECodingException("An unexpected problem occurred while trying to access the required host services."); } if (CatalogDAO.CatalogDAOFactory.isSetup()){ throw new PEException("An existing catalog service is currently running, please restart and try the upgrade again."); } Upgrader upgrader = new Upgrader(props); upgrader.upgrade(stdout); } }