001    /**
002     * Copyright (c) 2000-present Liferay, Inc. All rights reserved.
003     *
004     * This library is free software; you can redistribute it and/or modify it under
005     * the terms of the GNU Lesser General Public License as published by the Free
006     * Software Foundation; either version 2.1 of the License, or (at your option)
007     * any later version.
008     *
009     * This library is distributed in the hope that it will be useful, but WITHOUT
010     * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
011     * FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more
012     * details.
013     */
014    
015    package com.liferay.portal.upgrade.util;
016    
017    import com.liferay.portal.kernel.dao.jdbc.DataAccess;
018    import com.liferay.portal.kernel.log.Log;
019    import com.liferay.portal.kernel.log.LogFactoryUtil;
020    import com.liferay.portal.kernel.upgrade.UpgradeProcess;
021    import com.liferay.portal.kernel.util.LoggingTimer;
022    import com.liferay.portal.kernel.util.StringBundler;
023    
024    import java.io.IOException;
025    
026    import java.sql.Connection;
027    import java.sql.PreparedStatement;
028    import java.sql.ResultSet;
029    import java.sql.SQLException;
030    
031    import java.util.ArrayList;
032    import java.util.List;
033    import java.util.concurrent.Callable;
034    import java.util.concurrent.ExecutorService;
035    import java.util.concurrent.Executors;
036    import java.util.concurrent.Future;
037    
038    /**
039     * @author     Brian Wing Shun Chan
040     * @deprecated As of 7.0.0, replaced by {@link
041     *             com.liferay.portal.kernel.upgrade.BaseUpgradeCompanyId}
042     */
043    @Deprecated
044    public abstract class UpgradeCompanyId extends UpgradeProcess {
045    
046            @Override
047            protected void doUpgrade() throws Exception {
048                    List<Callable<Void>> callables = new ArrayList<>();
049    
050                    for (TableUpdater tableUpdater : getTableUpdaters()) {
051                            if (!hasColumn(tableUpdater.getTableName(), "companyId")) {
052                                    tableUpdater.setCreateCompanyIdColumn(true);
053                            }
054    
055                            callables.add(tableUpdater);
056                    }
057    
058                    ExecutorService executorService = Executors.newFixedThreadPool(
059                            callables.size());
060    
061                    try {
062                            List<Future<Void>> futures = executorService.invokeAll(callables);
063    
064                            for (Future<Void> future : futures) {
065                                    future.get();
066                            }
067                    }
068                    finally {
069                            executorService.shutdown();
070                    }
071            }
072    
073            protected abstract TableUpdater[] getTableUpdaters();
074    
075            protected class TableUpdater implements Callable<Void> {
076    
077                    public TableUpdater(
078                            String tableName, String foreignTableName,
079                            String foreignColumnName) {
080    
081                            _tableName = tableName;
082    
083                            _columnName = foreignColumnName;
084    
085                            _foreignNamesArray = new String[][] {
086                                    new String[] {foreignTableName, foreignColumnName}
087                            };
088                    }
089    
090                    public TableUpdater(
091                            String tableName, String columnName, String[][] foreignNamesArray) {
092    
093                            _tableName = tableName;
094                            _columnName = columnName;
095                            _foreignNamesArray = foreignNamesArray;
096                    }
097    
098                    @Override
099                    public final Void call() throws Exception {
100                            try (LoggingTimer loggingTimer = new LoggingTimer(_tableName);
101                                    Connection connection =
102                                            DataAccess.getUpgradeOptimizedConnection()) {
103    
104                                    if (_createCompanyIdColumn) {
105                                            if (_log.isInfoEnabled()) {
106                                                    _log.info(
107                                                            "Adding column companyId to table " + _tableName);
108                                            }
109    
110                                            runSQL(
111                                                    connection,
112                                                    "alter table " + _tableName +" add companyId LONG");
113                                    }
114                                    else {
115                                            if (_log.isInfoEnabled()) {
116                                                    _log.info(
117                                                            "Skipping the creation of companyId column for " +
118                                                                    "table " + _tableName);
119                                            }
120                                    }
121    
122                                    update(connection);
123                            }
124    
125                            return null;
126                    }
127    
128                    public String getTableName() {
129                            return _tableName;
130                    }
131    
132                    public void setCreateCompanyIdColumn(boolean createCompanyIdColumn) {
133                            _createCompanyIdColumn = createCompanyIdColumn;
134                    }
135    
136                    public void update(Connection connection)
137                            throws IOException, SQLException {
138    
139                            for (String[] foreignNames : _foreignNamesArray) {
140                                    runSQL(
141                                            connection,
142                                            getUpdateSQL(connection, foreignNames[0], foreignNames[1]));
143                            }
144                    }
145    
146                    protected List<Long> getCompanyIds(Connection connection)
147                            throws SQLException {
148    
149                            List<Long> companyIds = new ArrayList<>();
150    
151                            try (PreparedStatement ps = connection.prepareStatement(
152                                            "select companyId from Company");
153                                    ResultSet rs = ps.executeQuery()) {
154    
155                                    while (rs.next()) {
156                                            long companyId = rs.getLong(1);
157    
158                                            companyIds.add(companyId);
159                                    }
160                            }
161    
162                            return companyIds;
163                    }
164    
165                    protected String getSelectSQL(
166                                    Connection connection, String foreignTableName,
167                                    String foreignColumnName)
168                            throws SQLException {
169    
170                            List<Long> companyIds = getCompanyIds(connection);
171    
172                            if (companyIds.size() == 1) {
173                                    return String.valueOf(companyIds.get(0));
174                            }
175    
176                            StringBundler sb = new StringBundler(10);
177    
178                            sb.append("select max(companyId) from ");
179                            sb.append(foreignTableName);
180                            sb.append(" where ");
181                            sb.append(foreignTableName);
182                            sb.append(".");
183                            sb.append(foreignColumnName);
184                            sb.append(" = ");
185                            sb.append(_tableName);
186                            sb.append(".");
187                            sb.append(_columnName);
188    
189                            return sb.toString();
190                    }
191    
192                    protected String getUpdateSQL(
193                                    Connection connection, String foreignTableName,
194                                    String foreignColumnName)
195                            throws SQLException {
196    
197                            return getUpdateSQL(
198                                    getSelectSQL(connection, foreignTableName, foreignColumnName));
199                    }
200    
201                    protected String getUpdateSQL(String selectSQL) {
202                            StringBundler sb = new StringBundler(5);
203    
204                            sb.append("update ");
205                            sb.append(_tableName);
206                            sb.append(" set companyId = (");
207                            sb.append(selectSQL);
208                            sb.append(")");
209    
210                            return sb.toString();
211                    }
212    
213                    private final String _columnName;
214                    private boolean _createCompanyIdColumn;
215                    private final String[][] _foreignNamesArray;
216                    private final String _tableName;
217    
218            }
219    
220            private static final Log _log = LogFactoryUtil.getLog(
221                    UpgradeCompanyId.class);
222    
223    }