001/*
002 * Copyright (c) 2006-2011 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the Eclipse Public License v1.0
006 * which accompanies this distribution, and is available at
007 * http://www.eclipse.org/legal/epl-v10.html
008 *
009 * Contributors:
010 *     Arnaud Kervern
011 *     Florent Guillaume
012 */
013package org.nuxeo.ecm.core.storage.sql.jdbc;
014
015import java.sql.SQLException;
016import java.util.ArrayList;
017import java.util.List;
018
019import org.apache.commons.logging.Log;
020import org.apache.commons.logging.LogFactory;
021import org.nuxeo.ecm.core.storage.sql.jdbc.db.Column;
022
023/**
024 * Helper to provide SQL migration calls while adding a column.
025 *
026 * @since 5.4.2
027 */
028public class TableUpgrader {
029
030    protected static class TableUpgrade {
031        public final String tableKey;
032
033        public final String columnName;
034
035        public final String sqlProcedure;
036
037        public final String testProp;
038
039        public TableUpgrade(String tableKey, String columnName, String sqlProcedure, String testProp) {
040            this.tableKey = tableKey;
041            this.columnName = columnName;
042            this.sqlProcedure = sqlProcedure;
043            this.testProp = testProp;
044        }
045    }
046
047    protected List<TableUpgrade> tableUpgrades = new ArrayList<TableUpgrade>();
048
049    private JDBCMapper mapper;
050
051    private static final Log log = LogFactory.getLog(TableUpgrader.class);
052
053    public TableUpgrader(JDBCMapper mapper) {
054        this.mapper = mapper;
055    }
056
057    /**
058     * Add a couple table/column associated with a sql procedure to be executed when the column is added and a a test
059     * flag to force his execution.
060     *
061     * @param tableKey table name
062     * @param columnName desired added column
063     * @param sqlProcedure sql procedure name
064     * @param testProp test flag name
065     */
066    public void add(String tableKey, String columnName, String sqlProcedure, String testProp) {
067        tableUpgrades.add(new TableUpgrade(tableKey, columnName, sqlProcedure, testProp));
068    }
069
070    /**
071     * Check if there is an added column that match with a upgrade process. If one exists, it executes the associated
072     * sql in the category. If not, nothing happend.
073     *
074     * @param tableKey table name
075     * @param addedColumns list of added column
076     * @throws SQLException Exception thrown by JDBC
077     */
078    public void upgrade(String tableKey, List<Column> addedColumns) throws SQLException {
079        for (TableUpgrade upgrade : tableUpgrades) {
080            if (!upgrade.tableKey.equals(tableKey)) {
081                continue;
082            }
083            boolean doUpgrade;
084            if (addedColumns == null) {
085                // table created
086                doUpgrade = mapper.testProps.containsKey(upgrade.testProp);
087            } else {
088                // columns added
089                doUpgrade = false;
090                for (Column col : addedColumns) {
091                    if (col.getKey().equals(upgrade.columnName)) {
092                        doUpgrade = true;
093                        break;
094                    }
095                }
096            }
097            if (doUpgrade) {
098                log.info("Upgrading table: " + tableKey);
099                mapper.sqlInfo.executeSQLStatements(upgrade.sqlProcedure, mapper);
100            }
101        }
102    }
103}